From e178ddd9e1e16d1a3f52492799692e289eefcf8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20D=C3=B6singer?= Date: Tue, 5 Aug 2008 14:23:00 -0500 Subject: [PATCH] wined3d: Use a swapchain for GDI surfaces. This is a long-needed cleanup aimed at removing the ddraw_primary, ddraw_window, ddraw_width and ddraw_height members from IWineD3DDeviceImpl, which just do not belong there. Destination window and screen handling is supposed to be done by swapchains. --- dlls/d3d8/device.c | 2 +- dlls/d3d9/swapchain.c | 2 +- dlls/ddraw/ddraw.c | 94 ++++++++++- dlls/ddraw/ddraw_private.h | 1 + dlls/ddraw/surface.c | 64 ++++---- dlls/wined3d/Makefile.in | 1 + dlls/wined3d/device.c | 110 ++++++++++--- dlls/wined3d/surface.c | 7 +- dlls/wined3d/surface_gdi.c | 222 +++----------------------- dlls/wined3d/swapchain_gdi.c | 264 +++++++++++++++++++++++++++++++ dlls/wined3d/wined3d_private.h | 3 +- include/wine/wined3d_interface.h | 8 +- 12 files changed, 517 insertions(+), 261 deletions(-) create mode 100644 dlls/wined3d/swapchain_gdi.c diff --git a/dlls/d3d8/device.c b/dlls/d3d8/device.c index 476abe90b42..d1ae4762f2b 100644 --- a/dlls/d3d8/device.c +++ b/dlls/d3d8/device.c @@ -307,7 +307,7 @@ static HRESULT WINAPI IDirect3DDevice8Impl_CreateAdditionalSwapChain(LPDIRECT3DD localParameters.PresentationInterval = pPresentationParameters->FullScreen_PresentationInterval; EnterCriticalSection(&d3d8_cs); - hrc = IWineD3DDevice_CreateAdditionalSwapChain(This->WineD3DDevice, &localParameters, &object->wineD3DSwapChain, (IUnknown*)object, D3D8CB_CreateRenderTarget, D3D8CB_CreateDepthStencilSurface); + hrc = IWineD3DDevice_CreateAdditionalSwapChain(This->WineD3DDevice, &localParameters, &object->wineD3DSwapChain, (IUnknown*)object, D3D8CB_CreateRenderTarget, D3D8CB_CreateDepthStencilSurface, SURFACE_OPENGL); LeaveCriticalSection(&d3d8_cs); pPresentationParameters->BackBufferWidth = localParameters.BackBufferWidth; diff --git a/dlls/d3d9/swapchain.c b/dlls/d3d9/swapchain.c index 421230f8102..0dd9b8f2d17 100644 --- a/dlls/d3d9/swapchain.c +++ b/dlls/d3d9/swapchain.c @@ -229,7 +229,7 @@ HRESULT WINAPI IDirect3DDevice9Impl_CreateAdditionalSwapChain(LPDIRECT3DDEVICE localParameters.PresentationInterval = pPresentationParameters->PresentationInterval; EnterCriticalSection(&d3d9_cs); - hrc = IWineD3DDevice_CreateAdditionalSwapChain(This->WineD3DDevice, &localParameters, &object->wineD3DSwapChain, (IUnknown*)object, D3D9CB_CreateRenderTarget, D3D9CB_CreateDepthStencilSurface); + hrc = IWineD3DDevice_CreateAdditionalSwapChain(This->WineD3DDevice, &localParameters, &object->wineD3DSwapChain, (IUnknown*)object, D3D9CB_CreateRenderTarget, D3D9CB_CreateDepthStencilSurface, SURFACE_OPENGL); LeaveCriticalSection(&d3d9_cs); pPresentationParameters->BackBufferWidth = localParameters.BackBufferWidth; diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c index 5a8ea0ee5d2..d037769b1b1 100644 --- a/dlls/ddraw/ddraw.c +++ b/dlls/ddraw/ddraw.c @@ -48,6 +48,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(ddraw); static BOOL IDirectDrawImpl_DDSD_Match(const DDSURFACEDESC2* requested, const DDSURFACEDESC2* provided); static HRESULT WINAPI IDirectDrawImpl_AttachD3DDevice(IDirectDrawImpl *This, IDirectDrawSurfaceImpl *primary); static HRESULT WINAPI IDirectDrawImpl_CreateNewSurface(IDirectDrawImpl *This, DDSURFACEDESC2 *pDDSD, IDirectDrawSurfaceImpl **ppSurf, UINT level); +static HRESULT WINAPI IDirectDrawImpl_CreateGDISwapChain(IDirectDrawImpl *This, IDirectDrawSurfaceImpl *primary); /* Device identifier. Don't relay it to WineD3D */ static const DDDEVICEIDENTIFIER2 deviceidentifier = @@ -1626,6 +1627,7 @@ IDirectDrawImpl_RecreateSurfacesCallback(IDirectDrawSurface7 *surf, IUnknown *Parent; IParentImpl *parImpl = NULL; IWineD3DSurface *wineD3DSurface; + IWineD3DSwapChain *swapchain; HRESULT hr; void *tmp; IWineD3DClipper *clipper = NULL; @@ -1650,6 +1652,8 @@ IDirectDrawImpl_RecreateSurfacesCallback(IDirectDrawSurface7 *surf, if(surfImpl->ImplType == This->ImplType) return DDENUMRET_OK; /* Continue */ /* Get the objects */ + swapchain = surfImpl->wineD3DSwapChain; + surfImpl->wineD3DSwapChain = NULL; wineD3DSurface = surfImpl->WineD3DSurface; IWineD3DSurface_GetParent(wineD3DSurface, &Parent); IUnknown_Release(Parent); /* For the getParent */ @@ -1681,6 +1685,17 @@ IDirectDrawImpl_RecreateSurfacesCallback(IDirectDrawSurface7 *surf, hr = IWineD3DSurface_GetDesc(wineD3DSurface, &Desc); if(hr != D3D_OK) return hr; + if(swapchain) { + /* If there's a swapchain, it owns the IParent interface. Create a new one for the + * new surface + */ + parImpl = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*parImpl)); + ICOM_INIT_INTERFACE(parImpl, IParent, IParent_Vtbl); + parImpl->ref = 1; + + Parent = (IUnknown *) parImpl; + } + /* Create the new surface */ hr = IWineD3DDevice_CreateSurface(This->wineD3DDevice, Width, Height, Format, @@ -1711,10 +1726,23 @@ IDirectDrawImpl_RecreateSurfacesCallback(IDirectDrawSurface7 *surf, } /* TODO: Copy the surface content, except for render targets */ - if(IWineD3DSurface_Release(wineD3DSurface) == 0) - TRACE("Surface released successful, next surface\n"); - else - ERR("Something's still holding the old WineD3DSurface\n"); + /* If there's a swapchain, it owns the wined3d surfaces. So Destroy + * the swapchain + */ + if(swapchain) { + /* The backbuffers have the swapchain set as well, but the primary + * owns it and destroys it + */ + if(surfImpl->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) { + IWineD3DDevice_UninitGDI(This->wineD3DDevice, D3D7CB_DestroySwapChain); + } + surfImpl->isRenderTarget = FALSE; + } else { + if(IWineD3DSurface_Release(wineD3DSurface) == 0) + TRACE("Surface released successful, next surface\n"); + else + ERR("Something's still holding the old WineD3DSurface\n"); + } surfImpl->ImplType = This->ImplType; @@ -2711,6 +2739,8 @@ IDirectDrawImpl_CreateSurface(IDirectDraw7 *iface, LeaveCriticalSection(&ddraw_cs); return hr; } + } else if(!(This->d3d_initialized) && desc2.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) { + IDirectDrawImpl_CreateGDISwapChain(This, object); } /* Addref the ddraw interface to keep an reference for each surface */ @@ -3117,6 +3147,7 @@ D3D7CB_CreateAdditionalSwapChain(IUnknown *device, IParentImpl *object = NULL; HRESULT res = D3D_OK; IWineD3DSwapChain *swapchain; + IDirectDrawSurfaceImpl *iterator; TRACE("(%p) call back\n", device); object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IParentImpl)); @@ -3135,7 +3166,8 @@ D3D7CB_CreateAdditionalSwapChain(IUnknown *device, &swapchain, (IUnknown*) ICOM_INTERFACE(object, IParent), D3D7CB_CreateRenderTarget, - D3D7CB_CreateDepthStencilSurface); + D3D7CB_CreateDepthStencilSurface, + This->ImplType); if (res != D3D_OK) { FIXME("(%p) call to IWineD3DDevice_CreateAdditionalSwapChain failed\n", This); @@ -3146,11 +3178,63 @@ D3D7CB_CreateAdditionalSwapChain(IUnknown *device, { *ppSwapChain = swapchain; object->child = (IUnknown *) swapchain; + This->d3d_target->wineD3DSwapChain = swapchain; + iterator = This->d3d_target->complex_array[0]; + while(iterator) { + iterator->wineD3DSwapChain = swapchain; + iterator = iterator->complex_array[0]; + } } return res; } +static HRESULT WINAPI IDirectDrawImpl_CreateGDISwapChain(IDirectDrawImpl *This, + IDirectDrawSurfaceImpl *primary) { + HRESULT hr; + WINED3DPRESENT_PARAMETERS presentation_parameters; + HWND window; + + hr = IWineD3DDevice_GetHWND(This->wineD3DDevice, + &window); + if(FAILED(hr)) { + return hr; + } + + memset(&presentation_parameters, 0, sizeof(presentation_parameters)); + + /* Use the surface description for the device parameters, not the + * Device settings. The app might render to an offscreen surface + */ + presentation_parameters.BackBufferWidth = primary->surface_desc.dwWidth; + presentation_parameters.BackBufferHeight = primary->surface_desc.dwHeight; + presentation_parameters.BackBufferFormat = PixelFormat_DD2WineD3D(&primary->surface_desc.u4.ddpfPixelFormat); + presentation_parameters.BackBufferCount = (primary->surface_desc.dwFlags & DDSD_BACKBUFFERCOUNT) ? primary->surface_desc.dwBackBufferCount : 0; + presentation_parameters.MultiSampleType = WINED3DMULTISAMPLE_NONE; + presentation_parameters.MultiSampleQuality = 0; + presentation_parameters.SwapEffect = WINED3DSWAPEFFECT_FLIP; + presentation_parameters.hDeviceWindow = window; + presentation_parameters.Windowed = !(This->cooperative_level & DDSCL_FULLSCREEN); + presentation_parameters.EnableAutoDepthStencil = FALSE; /* Not on GDI swapchains */ + presentation_parameters.AutoDepthStencilFormat = 0; + presentation_parameters.Flags = 0; + presentation_parameters.FullScreen_RefreshRateInHz = WINED3DPRESENT_RATE_DEFAULT; /* Default rate: It's already set */ + presentation_parameters.PresentationInterval = WINED3DPRESENT_INTERVAL_DEFAULT; + + This->d3d_target = primary; + hr = IWineD3DDevice_InitGDI(This->wineD3DDevice, + &presentation_parameters, + D3D7CB_CreateAdditionalSwapChain); + This->d3d_target = NULL; + + if (hr != D3D_OK) + { + FIXME("(%p) call to IWineD3DDevice_CreateAdditionalSwapChain failed\n", This); + primary->wineD3DSwapChain = NULL; + } + return hr; +} + /***************************************************************************** * IDirectDrawImpl_AttachD3DDevice * diff --git a/dlls/ddraw/ddraw_private.h b/dlls/ddraw/ddraw_private.h index 56908cba8fe..b7816d7ab75 100644 --- a/dlls/ddraw/ddraw_private.h +++ b/dlls/ddraw/ddraw_private.h @@ -228,6 +228,7 @@ struct IDirectDrawSurfaceImpl IDirectDrawImpl *ddraw; IWineD3DSurface *WineD3DSurface; IWineD3DBaseTexture *wineD3DTexture; + IWineD3DSwapChain *wineD3DSwapChain; /* This implementation handles attaching surfaces to other surfaces */ IDirectDrawSurfaceImpl *next_attached; diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c index 1cf4d5724af..b4129b3abf3 100644 --- a/dlls/ddraw/surface.c +++ b/dlls/ddraw/surface.c @@ -307,40 +307,46 @@ IDirectDrawSurfaceImpl_Release(IDirectDrawSurface7 *iface) IWineD3DBaseTexture_Release(This->wineD3DTexture); } /* If it's the RenderTarget, destroy the d3ddevice */ - else if( (ddraw->d3d_initialized) && (This == ddraw->d3d_target)) + else if(This->wineD3DSwapChain) { - TRACE("(%p) Destroying the render target, uninitializing D3D\n", This); + if((ddraw->d3d_initialized) && (This == ddraw->d3d_target)) { + TRACE("(%p) Destroying the render target, uninitializing D3D\n", This); - /* Unset any index buffer, just to be sure */ - IWineD3DDevice_SetIndices(ddraw->wineD3DDevice, NULL); - IWineD3DDevice_SetDepthStencilSurface(ddraw->wineD3DDevice, NULL); - IWineD3DDevice_SetVertexDeclaration(ddraw->wineD3DDevice, NULL); - for(i = 0; i < ddraw->numConvertedDecls; i++) - { - IWineD3DVertexDeclaration_Release(ddraw->decls[i].decl); - } - HeapFree(GetProcessHeap(), 0, ddraw->decls); - ddraw->numConvertedDecls = 0; - - if(IWineD3DDevice_Uninit3D(ddraw->wineD3DDevice, D3D7CB_DestroyDepthStencilSurface, D3D7CB_DestroySwapChain) != D3D_OK) - { - /* Not good */ - ERR("(%p) Failed to uninit 3D\n", This); - } - else - { - /* Free the d3d window if one was created */ - if(ddraw->d3d_window != 0) + /* Unset any index buffer, just to be sure */ + IWineD3DDevice_SetIndices(ddraw->wineD3DDevice, NULL); + IWineD3DDevice_SetDepthStencilSurface(ddraw->wineD3DDevice, NULL); + IWineD3DDevice_SetVertexDeclaration(ddraw->wineD3DDevice, NULL); + for(i = 0; i < ddraw->numConvertedDecls; i++) { - TRACE(" (%p) Destroying the hidden render window %p\n", This, ddraw->d3d_window); - DestroyWindow(ddraw->d3d_window); - ddraw->d3d_window = 0; + IWineD3DVertexDeclaration_Release(ddraw->decls[i].decl); } - /* Unset the pointers */ - } + HeapFree(GetProcessHeap(), 0, ddraw->decls); + ddraw->numConvertedDecls = 0; - ddraw->d3d_initialized = FALSE; - ddraw->d3d_target = NULL; + if(IWineD3DDevice_Uninit3D(ddraw->wineD3DDevice, D3D7CB_DestroyDepthStencilSurface, D3D7CB_DestroySwapChain) != D3D_OK) + { + /* Not good */ + ERR("(%p) Failed to uninit 3D\n", This); + } + else + { + /* Free the d3d window if one was created */ + if(ddraw->d3d_window != 0) + { + TRACE(" (%p) Destroying the hidden render window %p\n", This, ddraw->d3d_window); + DestroyWindow(ddraw->d3d_window); + ddraw->d3d_window = 0; + } + /* Unset the pointers */ + } + + This->wineD3DSwapChain = NULL; /* Uninit3D releases the swapchain */ + ddraw->d3d_initialized = FALSE; + ddraw->d3d_target = NULL; + } else { + IWineD3DDevice_UninitGDI(ddraw->wineD3DDevice, D3D7CB_DestroySwapChain); + This->wineD3DSwapChain = NULL; + } /* Reset to the default surface implementation type. This is needed if apps use * non render target surfaces and expect blits to work after destroying the render diff --git a/dlls/wined3d/Makefile.in b/dlls/wined3d/Makefile.in index 7591b4d0ca8..dd0984ef6f7 100644 --- a/dlls/wined3d/Makefile.in +++ b/dlls/wined3d/Makefile.in @@ -30,6 +30,7 @@ C_SRCS = \ surface.c \ surface_gdi.c \ swapchain.c \ + swapchain_gdi.c \ swapchain_base.c \ texture.c \ utils.c \ diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 49a72eb169b..836b318317f 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -718,10 +718,6 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateSurface(IWineD3DDevice *iface, U This, Width, Height, Format, debug_d3dformat(Format), (WINED3DFMT_D16_LOCKABLE == Format), *ppSurface, object->resource.allocatedMemory, object->resource.size); - /* Store the DirectDraw primary surface. This is the first rendertarget surface created */ - if( (Usage & WINED3DUSAGE_RENDERTARGET) && (!This->ddraw_primary) ) - This->ddraw_primary = (IWineD3DSurface *) object; - /* Look at the implementation and set the correct Vtable */ switch(Impl) { case SURFACE_OPENGL: @@ -1387,7 +1383,8 @@ static void WINAPI IWineD3DDeviceImpl_RestoreWindow(IWineD3DDevice *iface, HWND static HRESULT WINAPI IWineD3DDeviceImpl_CreateAdditionalSwapChain(IWineD3DDevice* iface, WINED3DPRESENT_PARAMETERS* pPresentationParameters, IWineD3DSwapChain** ppSwapChain, IUnknown* parent, D3DCB_CREATERENDERTARGETFN D3DCB_CreateRenderTarget, - D3DCB_CREATEDEPTHSTENCILSURFACEFN D3DCB_CreateDepthStencil) { + D3DCB_CREATEDEPTHSTENCILSURFACEFN D3DCB_CreateDepthStencil, + WINED3DSURFTYPE surface_type) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; HDC hDc; @@ -1414,6 +1411,17 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateAdditionalSwapChain(IWineD3DDevic } D3DCREATEOBJECTINSTANCE(object, SwapChain) + switch(surface_type) { + case SURFACE_GDI: + object->lpVtbl = &IWineGDISwapChain_Vtbl; + break; + case SURFACE_OPENGL: + object->lpVtbl = &IWineD3DSwapChain_Vtbl; + break; + case SURFACE_UNKNOWN: + FIXME("Caller tried to create a SURFACE_UNKNOWN swapchain\n"); + return WINED3DERR_INVALIDCALL; + } /********************* * Lookup the window Handle and the relating X window handle @@ -1485,7 +1493,9 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateAdditionalSwapChain(IWineD3DDevic NULL /* pShared (always null)*/); if (object->frontBuffer != NULL) { IWineD3DSurface_SetContainer(object->frontBuffer, (IWineD3DBase *)object); - IWineD3DSurface_ModifyLocation(object->frontBuffer, SFLAG_INDRAWABLE, TRUE); + if(surface_type == SURFACE_OPENGL) { + IWineD3DSurface_ModifyLocation(object->frontBuffer, SFLAG_INDRAWABLE, TRUE); + } } else { ERR("Failed to create the front buffer\n"); goto error; @@ -1530,14 +1540,16 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateAdditionalSwapChain(IWineD3DDevic return E_OUTOFMEMORY; object->num_contexts = 1; - object->context[0] = CreateContext(This, (IWineD3DSurfaceImpl *) object->frontBuffer, object->win_handle, FALSE /* pbuffer */, pPresentationParameters); - if (!object->context[0]) { - ERR("Failed to create a new context\n"); - hr = WINED3DERR_NOTAVAILABLE; - goto error; - } else { - TRACE("Context created (HWND=%p, glContext=%p)\n", - object->win_handle, object->context[0]->glCtx); + if(surface_type == SURFACE_OPENGL) { + object->context[0] = CreateContext(This, (IWineD3DSurfaceImpl *) object->frontBuffer, object->win_handle, FALSE /* pbuffer */, pPresentationParameters); + if (!object->context[0]) { + ERR("Failed to create a new context\n"); + hr = WINED3DERR_NOTAVAILABLE; + goto error; + } else { + TRACE("Context created (HWND=%p, glContext=%p)\n", + object->win_handle, object->context[0]->glCtx); + } } /********************* @@ -1571,23 +1583,27 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateAdditionalSwapChain(IWineD3DDevic ERR("Cannot create new back buffer\n"); goto error; } - ENTER_GL(); - glDrawBuffer(GL_BACK); - checkGLcall("glDrawBuffer(GL_BACK)"); - LEAVE_GL(); + if(surface_type == SURFACE_OPENGL) { + ENTER_GL(); + glDrawBuffer(GL_BACK); + checkGLcall("glDrawBuffer(GL_BACK)"); + LEAVE_GL(); + } } } else { object->backBuffer = NULL; /* Single buffering - draw to front buffer */ - ENTER_GL(); - glDrawBuffer(GL_FRONT); - checkGLcall("glDrawBuffer(GL_FRONT)"); - LEAVE_GL(); + if(surface_type == SURFACE_OPENGL) { + ENTER_GL(); + glDrawBuffer(GL_FRONT); + checkGLcall("glDrawBuffer(GL_FRONT)"); + LEAVE_GL(); + } } /* Under directX swapchains share the depth stencil, so only create one depth-stencil */ - if (pPresentationParameters->EnableAutoDepthStencil && hr == WINED3D_OK) { + if (pPresentationParameters->EnableAutoDepthStencil && hr == WINED3D_OK && surface_type == SURFACE_OPENGL) { TRACE("Creating depth stencil buffer\n"); if (This->auto_depth_stencil_buffer == NULL ) { hr = D3DCB_CreateDepthStencil(This->parent, @@ -2240,6 +2256,33 @@ err_out: return hr; } +static HRESULT WINAPI IWineD3DDeviceImpl_InitGDI(IWineD3DDevice *iface, WINED3DPRESENT_PARAMETERS* pPresentationParameters, D3DCB_CREATEADDITIONALSWAPCHAIN D3DCB_CreateAdditionalSwapChain) { + IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface; + IWineD3DSwapChainImpl *swapchain = NULL; + HRESULT hr; + + /* Setup the implicit swapchain */ + TRACE("Creating implicit swapchain\n"); + hr=D3DCB_CreateAdditionalSwapChain(This->parent, pPresentationParameters, (IWineD3DSwapChain **)&swapchain); + if (FAILED(hr) || !swapchain) { + WARN("Failed to create implicit swapchain\n"); + goto err_out; + } + + This->NumberOfSwapChains = 1; + This->swapchains = HeapAlloc(GetProcessHeap(), 0, This->NumberOfSwapChains * sizeof(IWineD3DSwapChain *)); + if(!This->swapchains) { + ERR("Out of memory!\n"); + goto err_out; + } + This->swapchains[0] = (IWineD3DSwapChain *) swapchain; + return WINED3D_OK; + +err_out: + IWineD3DSwapChain_Release((IWineD3DSwapChain *) swapchain); + return hr; +} + static HRESULT WINAPI IWineD3DDeviceImpl_Uninit3D(IWineD3DDevice *iface, D3DCB_DESTROYSURFACEFN D3DCB_DestroyDepthStencilSurface, D3DCB_DESTROYSWAPCHAINFN D3DCB_DestroySwapChain) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface; int sampler; @@ -2377,6 +2420,23 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Uninit3D(IWineD3DDevice *iface, D3DCB_D return WINED3D_OK; } +static HRESULT WINAPI IWineD3DDeviceImpl_UninitGDI(IWineD3DDevice *iface, D3DCB_DESTROYSWAPCHAINFN D3DCB_DestroySwapChain) { + IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface; + unsigned int i; + + for(i=0; i < This->NumberOfSwapChains; i++) { + TRACE("Releasing the implicit swapchain %d\n", i); + if (D3DCB_DestroySwapChain(This->swapchains[i]) > 0) { + FIXME("(%p) Something's still holding the implicit swapchain\n", This); + } + } + + HeapFree(GetProcessHeap(), 0, This->swapchains); + This->swapchains = NULL; + This->NumberOfSwapChains = 0; + return WINED3D_OK; +} + static void WINAPI IWineD3DDeviceImpl_SetFullscreen(IWineD3DDevice *iface, BOOL fullscreen) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface; TRACE("(%p) Setting DDraw fullscreen mode to %s\n", This, fullscreen ? "true" : "false"); @@ -7644,7 +7704,9 @@ const IWineD3DDeviceVtbl IWineD3DDevice_Vtbl = IWineD3DDeviceImpl_CreatePalette, /*** Odd functions **/ IWineD3DDeviceImpl_Init3D, + IWineD3DDeviceImpl_InitGDI, IWineD3DDeviceImpl_Uninit3D, + IWineD3DDeviceImpl_UninitGDI, IWineD3DDeviceImpl_SetFullscreen, IWineD3DDeviceImpl_SetMultithreaded, IWineD3DDeviceImpl_EvictManagedResources, @@ -7790,7 +7852,9 @@ const IWineD3DDeviceVtbl IWineD3DDevice_DirtyConst_Vtbl = IWineD3DDeviceImpl_CreatePalette, /*** Odd functions **/ IWineD3DDeviceImpl_Init3D, + IWineD3DDeviceImpl_InitGDI, IWineD3DDeviceImpl_Uninit3D, + IWineD3DDeviceImpl_UninitGDI, IWineD3DDeviceImpl_SetFullscreen, IWineD3DDeviceImpl_SetMultithreaded, IWineD3DDeviceImpl_EvictManagedResources, diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c index 07c7076bd7f..dff833ed527 100644 --- a/dlls/wined3d/surface.c +++ b/dlls/wined3d/surface.c @@ -471,8 +471,6 @@ ULONG WINAPI IWineD3DSurfaceImpl_Release(IWineD3DSurface *iface) { HeapFree(GetProcessHeap(), 0, This->palette9); IWineD3DResourceImpl_CleanUp((IWineD3DResource *)iface); - if(iface == device->ddraw_primary) - device->ddraw_primary = NULL; if(This->overlay_dest) { list_remove(&This->overlay_entry); @@ -1460,7 +1458,10 @@ HRESULT WINAPI IWineD3DSurfaceImpl_GetDC(IWineD3DSurface *iface, HDC *pHDC) { if(This->palette) { pal = This->palette->palents; } else { - IWineD3DSurfaceImpl *dds_primary = (IWineD3DSurfaceImpl *)This->resource.wineD3DDevice->ddraw_primary; + IWineD3DSurfaceImpl *dds_primary; + IWineD3DSwapChainImpl *swapchain; + swapchain = (IWineD3DSwapChainImpl *)This->resource.wineD3DDevice->swapchains[0]; + dds_primary = (IWineD3DSurfaceImpl *)swapchain->frontBuffer; if (dds_primary && dds_primary->palette) pal = dds_primary->palette->palents; } diff --git a/dlls/wined3d/surface_gdi.c b/dlls/wined3d/surface_gdi.c index 1b1e5dbeb7d..7874f92c9b1 100644 --- a/dlls/wined3d/surface_gdi.c +++ b/dlls/wined3d/surface_gdi.c @@ -34,99 +34,6 @@ /* Use the d3d_surface debug channel to have one channel for all surfaces */ WINE_DEFAULT_DEBUG_CHANNEL(d3d_surface); -WINE_DECLARE_DEBUG_CHANNEL(fps); - -/***************************************************************************** - * x11_copy_to_screen - * - * Helper function that blts the front buffer contents to the target window - * - * Params: - * This: Surface to copy from - * rc: Rectangle to copy - * - *****************************************************************************/ -static void -x11_copy_to_screen(IWineD3DSurfaceImpl *This, - LPRECT rc) -{ - if(This->resource.usage & WINED3DUSAGE_RENDERTARGET) - { - POINT offset = {0,0}; - HWND hDisplayWnd; - HDC hDisplayDC; - HDC hSurfaceDC = 0; - RECT drawrect; - TRACE("(%p)->(%p): Copying to screen\n", This, rc); - - hSurfaceDC = This->hDC; - - hDisplayWnd = This->resource.wineD3DDevice->ddraw_window; - hDisplayDC = GetDCEx(hDisplayWnd, 0, DCX_CLIPSIBLINGS|DCX_CACHE); - if(rc) - { - TRACE(" copying rect (%d,%d)->(%d,%d), offset (%d,%d)\n", - rc->left, rc->top, rc->right, rc->bottom, offset.x, offset.y); - } - - /* Front buffer coordinates are screen coordinates. Map them to the destination - * window if not fullscreened - */ - if(!This->resource.wineD3DDevice->ddraw_fullscreen) { - ClientToScreen(hDisplayWnd, &offset); - } -#if 0 - /* FIXME: this doesn't work... if users really want to run - * X in 8bpp, then we need to call directly into display.drv - * (or Wine's equivalent), and force a private colormap - * without default entries. */ - if (This->palette) { - SelectPalette(hDisplayDC, This->palette->hpal, FALSE); - RealizePalette(hDisplayDC); /* sends messages => deadlocks */ - } -#endif - drawrect.left = 0; - drawrect.right = This->currentDesc.Width; - drawrect.top = 0; - drawrect.bottom = This->currentDesc.Height; - -#if 0 - /* TODO: Support clippers */ - if (This->clipper) - { - RECT xrc; - HWND hwnd = ((IWineD3DClipperImpl *) This->clipper)->hWnd; - if (hwnd && GetClientRect(hwnd,&xrc)) - { - OffsetRect(&xrc,offset.x,offset.y); - IntersectRect(&drawrect,&drawrect,&xrc); - } - } -#endif - if (rc) - { - IntersectRect(&drawrect,&drawrect,rc); - } - else - { - /* Only use this if the caller did not pass a rectangle, since - * due to double locking this could be the wrong one ... - */ - if (This->lockedRect.left != This->lockedRect.right) - { - IntersectRect(&drawrect,&drawrect,&This->lockedRect); - } - } - - BitBlt(hDisplayDC, - drawrect.left-offset.x, drawrect.top-offset.y, - drawrect.right-drawrect.left, drawrect.bottom-drawrect.top, - hSurfaceDC, - drawrect.left, drawrect.top, - SRCCOPY); - ReleaseDC(hDisplayWnd, hDisplayDC); - } -} /***************************************************************************** * IWineD3DSurface::Release, GDI version @@ -140,7 +47,6 @@ ULONG WINAPI IWineGDISurfaceImpl_Release(IWineD3DSurface *iface) { ULONG ref = InterlockedDecrement(&This->resource.ref); TRACE("(%p) : Releasing from %d\n", This, ref + 1); if (ref == 0) { - IWineD3DDeviceImpl *device = This->resource.wineD3DDevice; TRACE("(%p) : cleaning up\n", This); if(This->Flags & SFLAG_DIBSECTION) { @@ -157,8 +63,6 @@ ULONG WINAPI IWineGDISurfaceImpl_Release(IWineD3DSurface *iface) { HeapFree(GetProcessHeap(), 0, This->palette9); IWineD3DResourceImpl_CleanUp((IWineD3DResource *)iface); - if(iface == device->ddraw_primary) - device->ddraw_primary = NULL; if(This->overlay_dest) { list_remove(&This->overlay_entry); @@ -258,7 +162,7 @@ static HRESULT WINAPI IWineGDISurfaceImpl_UnlockRect(IWineD3DSurface *iface) { IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface; - IWineD3DDeviceImpl *dev = This->resource.wineD3DDevice; + IWineD3DSwapChainImpl *swapchain = NULL; TRACE("(%p)\n", This); if (!(This->Flags & SFLAG_LOCKED)) @@ -287,10 +191,11 @@ IWineGDISurfaceImpl_UnlockRect(IWineD3DSurface *iface) } #endif - /* Update the screen */ - if(This == (IWineD3DSurfaceImpl *) dev->ddraw_primary) - { - x11_copy_to_screen(This, &This->lockedRect); + /* Tell the swapchain to update the screen */ + IWineD3DSurface_GetContainer(iface, &IID_IWineD3DSwapChain, (void **) &swapchain); + if(swapchain) { + x11_copy_to_screen(swapchain, &This->lockedRect); + IWineD3DSwapChain_Release((IWineD3DSwapChain *) swapchain); } This->Flags &= ~SFLAG_LOCKED; @@ -317,101 +222,18 @@ IWineGDISurfaceImpl_Flip(IWineD3DSurface *iface, IWineD3DSurface *override, DWORD Flags) { - IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *) iface; - IWineD3DSurfaceImpl *Target = (IWineD3DSurfaceImpl *) override; - TRACE("(%p)->(%p,%x)\n", This, override, Flags); + IWineD3DSwapChainImpl *swapchain = NULL; + HRESULT hr; - TRACE("(%p) Flipping to surface %p\n", This, Target); - - if(Target == NULL) - { - ERR("(%p): Can't flip without a target\n", This); - return WINED3DERR_INVALIDCALL; + IWineD3DSurface_GetContainer(iface, &IID_IWineD3DSwapChain, (void **) &swapchain); + if(!swapchain) { + ERR("Flipped surface is not on a swapchain\n"); + return WINEDDERR_NOTFLIPPABLE; } - /* Flip the DC */ - { - HDC tmp; - tmp = This->hDC; - This->hDC = Target->hDC; - Target->hDC = tmp; - } - - /* Flip the DIBsection */ - { - HBITMAP tmp; - tmp = This->dib.DIBsection; - This->dib.DIBsection = Target->dib.DIBsection; - Target->dib.DIBsection = tmp; - } - - /* Flip the surface data */ - { - void* tmp; - - tmp = This->dib.bitmap_data; - This->dib.bitmap_data = Target->dib.bitmap_data; - Target->dib.bitmap_data = tmp; - - tmp = This->resource.allocatedMemory; - This->resource.allocatedMemory = Target->resource.allocatedMemory; - Target->resource.allocatedMemory = tmp; - - if(This->resource.heapMemory) { - ERR("GDI Surface %p has heap memory allocated\n", This); - } - if(Target->resource.heapMemory) { - ERR("GDI Surface %p has heap memory allocated\n", Target); - } - } - - /* client_memory should not be different, but just in case */ - { - BOOL tmp; - tmp = This->dib.client_memory; - This->dib.client_memory = Target->dib.client_memory; - Target->dib.client_memory = tmp; - } - - /* Useful for debugging */ -#if 0 - { - static unsigned int gen = 0; - char buffer[4096]; - ++gen; - if ((gen % 10) == 0) { - snprintf(buffer, sizeof(buffer), "/tmp/surface%p_type%u_level%u_%u.ppm", This, This->glDescription.target, This->glDescription.level, gen); - IWineD3DSurfaceImpl_SaveSnapshot(iface, buffer); - } - /* - * debugging crash code - if (gen == 250) { - void** test = NULL; - *test = 0; - } - */ - } -#endif - - /* Update the screen */ - x11_copy_to_screen(This, NULL); - - /* FPS support */ - if (TRACE_ON(fps)) - { - static long prev_time, frames; - - DWORD time = GetTickCount(); - frames++; - /* every 1.5 seconds */ - if (time - prev_time > 1500) { - TRACE_(fps)("@ approx %.2ffps\n", 1000.0*frames/(time - prev_time)); - prev_time = time; - frames = 0; - } - } - - return WINED3D_OK; + hr = IWineD3DSwapChain_Present((IWineD3DSwapChain *) swapchain, NULL, NULL, 0, NULL, 0); + IWineD3DSwapChain_Release((IWineD3DSwapChain *) swapchain); + return hr; } /***************************************************************************** @@ -588,7 +410,10 @@ HRESULT WINAPI IWineGDISurfaceImpl_GetDC(IWineD3DSurface *iface, HDC *pHDC) { if(This->palette) { pal = This->palette->palents; } else { - IWineD3DSurfaceImpl *dds_primary = (IWineD3DSurfaceImpl *)This->resource.wineD3DDevice->ddraw_primary; + IWineD3DSurfaceImpl *dds_primary; + IWineD3DSwapChainImpl *swapchain; + swapchain = (IWineD3DSwapChainImpl *)This->resource.wineD3DDevice->swapchains[0]; + dds_primary = (IWineD3DSurfaceImpl *)swapchain->frontBuffer; if (dds_primary && dds_primary->palette) pal = dds_primary->palette->palents; } @@ -637,6 +462,7 @@ HRESULT WINAPI IWineGDISurfaceImpl_RealizePalette(IWineD3DSurface *iface) { RGBQUAD col[256]; IWineD3DPaletteImpl *pal = This->palette; unsigned int n; + IWineD3DSwapChainImpl *swapchain; TRACE("(%p)\n", This); if (!pal) return WINED3D_OK; @@ -654,8 +480,12 @@ HRESULT WINAPI IWineGDISurfaceImpl_RealizePalette(IWineD3DSurface *iface) { /* Update the image because of the palette change. Some games like e.g Red Alert call SetEntries a lot to implement fading. */ - if(This == (IWineD3DSurfaceImpl *) This->resource.wineD3DDevice->ddraw_primary) - x11_copy_to_screen(This, NULL); + /* Tell the swapchain to update the screen */ + IWineD3DSurface_GetContainer(iface, &IID_IWineD3DSwapChain, (void **) &swapchain); + if(swapchain) { + x11_copy_to_screen(swapchain, &This->lockedRect); + IWineD3DSwapChain_Release((IWineD3DSwapChain *) swapchain); + } return WINED3D_OK; } diff --git a/dlls/wined3d/swapchain_gdi.c b/dlls/wined3d/swapchain_gdi.c new file mode 100644 index 00000000000..658ea2faaf0 --- /dev/null +++ b/dlls/wined3d/swapchain_gdi.c @@ -0,0 +1,264 @@ +/* + *IDirect3DSwapChain9 implementation + * + *Copyright 2002-2003 Jason Edmeades + *Copyright 2002-2003 Raphael Junqueira + *Copyright 2005 Oliver Stieber + *Copyright 2007-2008 Stefan Dösinger for CodeWeavers + * + *This library is free software; you can redistribute it and/or + *modify it under the terms of the GNU Lesser General Public + *License as published by the Free Software Foundation; either + *version 2.1 of the License, or (at your option) any later version. + * + *This library is distributed in the hope that it will be useful, + *but WITHOUT ANY WARRANTY; without even the implied warranty of + *MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + *Lesser General Public License for more details. + * + *You should have received a copy of the GNU Lesser General Public + *License along with this library; if not, write to the Free Software + *Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "config.h" +#include "wined3d_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(d3d); +WINE_DECLARE_DEBUG_CHANNEL(fps); + +static void WINAPI IWineGDISwapChainImpl_Destroy(IWineD3DSwapChain *iface, D3DCB_DESTROYSURFACEFN D3DCB_DestroyRenderback) { + IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface; + WINED3DDISPLAYMODE mode; + + TRACE("Destroying swapchain %p\n", iface); + + IWineD3DSwapChain_SetGammaRamp(iface, 0, &This->orig_gamma); + + /* release the ref to the front and back buffer parents */ + if(This->frontBuffer) { + IWineD3DSurface_SetContainer(This->frontBuffer, 0); + if(D3DCB_DestroyRenderback(This->frontBuffer) > 0) { + FIXME("(%p) Something's still holding the front buffer\n",This); + } + } + + if(This->backBuffer) { + int i; + for(i = 0; i < This->presentParms.BackBufferCount; i++) { + IWineD3DSurface_SetContainer(This->backBuffer[i], 0); + if(D3DCB_DestroyRenderback(This->backBuffer[i]) > 0) { + FIXME("(%p) Something's still holding the back buffer\n",This); + } + } + HeapFree(GetProcessHeap(), 0, This->backBuffer); + } + + /* Restore the screen resolution if we rendered in fullscreen + * This will restore the screen resolution to what it was before creating the swapchain. In case of d3d8 and d3d9 + * this will be the original desktop resolution. In case of d3d7 this will be a NOP because ddraw sets the resolution + * before starting up Direct3D, thus orig_width and orig_height will be equal to the modes in the presentation params + */ + if(This->presentParms.Windowed == FALSE) { + mode.Width = This->orig_width; + mode.Height = This->orig_height; + mode.RefreshRate = 0; + mode.Format = This->orig_fmt; + IWineD3DDevice_SetDisplayMode((IWineD3DDevice *) This->wineD3DDevice, 0, &mode); + } + + HeapFree(GetProcessHeap(), 0, This); +} + +/***************************************************************************** + * x11_copy_to_screen + * + * Helper function that blts the front buffer contents to the target window + * + * Params: + * This: Surface to copy from + * rc: Rectangle to copy + * + *****************************************************************************/ +void x11_copy_to_screen(IWineD3DSwapChainImpl *This, LPRECT rc) { + IWineD3DSurfaceImpl *front = (IWineD3DSurfaceImpl *) This->frontBuffer; + + if(front->resource.usage & WINED3DUSAGE_RENDERTARGET) { + POINT offset = {0,0}; + HWND hDisplayWnd; + HDC hDisplayDC; + HDC hSurfaceDC = 0; + RECT drawrect; + TRACE("(%p)->(%p): Copying to screen\n", front, rc); + + hSurfaceDC = front->hDC; + + hDisplayWnd = front->resource.wineD3DDevice->ddraw_window; + hDisplayDC = GetDCEx(hDisplayWnd, 0, DCX_CLIPSIBLINGS|DCX_CACHE); + if(rc) { + TRACE(" copying rect (%d,%d)->(%d,%d), offset (%d,%d)\n", + rc->left, rc->top, rc->right, rc->bottom, offset.x, offset.y); + } + + /* Front buffer coordinates are screen coordinates. Map them to the destination + * window if not fullscreened + */ + if(!front->resource.wineD3DDevice->ddraw_fullscreen) { + ClientToScreen(hDisplayWnd, &offset); + } +#if 0 + /* FIXME: This doesn't work... if users really want to run + * X in 8bpp, then we need to call directly into display.drv + * (or Wine's equivalent), and force a private colormap + * without default entries. */ + if (front->palette) { + SelectPalette(hDisplayDC, front->palette->hpal, FALSE); + RealizePalette(hDisplayDC); /* sends messages => deadlocks */ + } +#endif + drawrect.left = 0; + drawrect.right = front->currentDesc.Width; + drawrect.top = 0; + drawrect.bottom = front->currentDesc.Height; + +#if 0 + /* TODO: Support clippers */ + if (front->clipper) + { + RECT xrc; + HWND hwnd = ((IWineD3DClipperImpl *) front->clipper)->hWnd; + if (hwnd && GetClientRect(hwnd,&xrc)) + { + OffsetRect(&xrc,offset.x,offset.y); + IntersectRect(&drawrect,&drawrect,&xrc); + } + } +#endif + if (rc) { + IntersectRect(&drawrect,&drawrect,rc); + } + else { + /* Only use this if the caller did not pass a rectangle, since + * due to double locking this could be the wrong one ... + */ + if (front->lockedRect.left != front->lockedRect.right) { + IntersectRect(&drawrect,&drawrect,&front->lockedRect); + } + } + + BitBlt(hDisplayDC, + drawrect.left-offset.x, drawrect.top-offset.y, + drawrect.right-drawrect.left, drawrect.bottom-drawrect.top, + hSurfaceDC, + drawrect.left, drawrect.top, + SRCCOPY); + ReleaseDC(hDisplayWnd, hDisplayDC); + } +} + +static HRESULT WINAPI IWineGDISwapChainImpl_Present(IWineD3DSwapChain *iface, CONST RECT *pSourceRect, CONST RECT *pDestRect, HWND hDestWindowOverride, CONST RGNDATA *pDirtyRegion, DWORD dwFlags) { + IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *) iface; + IWineD3DSurfaceImpl *front, *back; + + if(!This->backBuffer) { + WARN("Swapchain doesn't have a backbuffer, returning WINED3DERR_INVALIDCALL\n"); + return WINED3DERR_INVALIDCALL; + } + front = (IWineD3DSurfaceImpl *) This->frontBuffer; + back = (IWineD3DSurfaceImpl *) This->backBuffer[0]; + + /* Flip the DC */ + { + HDC tmp; + tmp = front->hDC; + front->hDC = back->hDC; + back->hDC = tmp; + } + + /* Flip the DIBsection */ + { + HBITMAP tmp; + tmp = front->dib.DIBsection; + front->dib.DIBsection = back->dib.DIBsection; + back->dib.DIBsection = tmp; + } + + /* Flip the surface data */ + { + void* tmp; + + tmp = front->dib.bitmap_data; + front->dib.bitmap_data = back->dib.bitmap_data; + back->dib.bitmap_data = tmp; + + tmp = front->resource.allocatedMemory; + front->resource.allocatedMemory = back->resource.allocatedMemory; + back->resource.allocatedMemory = tmp; + + if(front->resource.heapMemory) { + ERR("GDI Surface %p has heap memory allocated\n", front); + } + if(back->resource.heapMemory) { + ERR("GDI Surface %p has heap memory allocated\n", back); + } + } + + /* client_memory should not be different, but just in case */ + { + BOOL tmp; + tmp = front->dib.client_memory; + front->dib.client_memory = back->dib.client_memory; + back->dib.client_memory = tmp; + } + + /* FPS support */ + if (TRACE_ON(fps)) + { + static long prev_time, frames; + + DWORD time = GetTickCount(); + frames++; + /* every 1.5 seconds */ + if (time - prev_time > 1500) { + TRACE_(fps)("@ approx %.2ffps\n", 1000.0*frames/(time - prev_time)); + prev_time = time; + frames = 0; + } + } + + x11_copy_to_screen(This, NULL); + + return WINED3D_OK; +} + +/* FIXME: This should not be needed, the base version is OK */ +HRESULT WINAPI IWineGDIBaseSwapChainImpl_GetDisplayMode(IWineD3DSwapChain *iface, WINED3DDISPLAYMODE*pMode) { + IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface; + IWineD3DDeviceImpl *device = This->wineD3DDevice; + + pMode->Width = device->ddraw_width; + pMode->Height = device->ddraw_height; + pMode->Format = device->ddraw_format; + pMode->RefreshRate = 0; + return WINED3D_OK; +} + +const IWineD3DSwapChainVtbl IWineGDISwapChain_Vtbl = +{ + /* IUnknown */ + IWineD3DBaseSwapChainImpl_QueryInterface, + IWineD3DBaseSwapChainImpl_AddRef, + IWineD3DBaseSwapChainImpl_Release, + /* IWineD3DSwapChain */ + IWineD3DBaseSwapChainImpl_GetParent, + IWineGDISwapChainImpl_Destroy, + IWineD3DBaseSwapChainImpl_GetDevice, + IWineGDISwapChainImpl_Present, + IWineD3DBaseSwapChainImpl_GetFrontBufferData, + IWineD3DBaseSwapChainImpl_GetBackBuffer, + IWineD3DBaseSwapChainImpl_GetRasterStatus, + IWineD3DBaseSwapChainImpl_GetDisplayMode, + IWineD3DBaseSwapChainImpl_GetPresentParameters, + IWineD3DBaseSwapChainImpl_SetGammaRamp, + IWineD3DBaseSwapChainImpl_GetGammaRamp +}; diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 0629dd25560..0c163f43ff5 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -918,7 +918,6 @@ struct IWineD3DDeviceImpl /* DirectDraw stuff */ HWND ddraw_window; - IWineD3DSurface *ddraw_primary; DWORD ddraw_width, ddraw_height; WINED3DFORMAT ddraw_format; BOOL ddraw_fullscreen; @@ -1745,6 +1744,8 @@ typedef struct IWineD3DSwapChainImpl } IWineD3DSwapChainImpl; extern const IWineD3DSwapChainVtbl IWineD3DSwapChain_Vtbl; +const IWineD3DSwapChainVtbl IWineGDISwapChain_Vtbl; +void x11_copy_to_screen(IWineD3DSwapChainImpl *This, LPRECT rc); HRESULT WINAPI IWineD3DBaseSwapChainImpl_QueryInterface(IWineD3DSwapChain *iface, REFIID riid, LPVOID *ppobj); ULONG WINAPI IWineD3DBaseSwapChainImpl_AddRef(IWineD3DSwapChain *iface); diff --git a/include/wine/wined3d_interface.h b/include/wine/wined3d_interface.h index b478cda4292..e8b4d94290b 100644 --- a/include/wine/wined3d_interface.h +++ b/include/wine/wined3d_interface.h @@ -367,14 +367,16 @@ DECLARE_INTERFACE_(IWineD3DDevice,IWineD3DBase) STDMETHOD(CreateVolume)(THIS_ UINT Width, UINT Height, UINT Depth, DWORD Usage, WINED3DFORMAT Format, WINED3DPOOL Pool, struct IWineD3DVolume** ppVolumeTexture, HANDLE* pSharedHandle, IUnknown *parent) PURE; STDMETHOD(CreateCubeTexture)(THIS_ UINT EdgeLength, UINT Levels, DWORD Usage, WINED3DFORMAT Format, WINED3DPOOL Pool, struct IWineD3DCubeTexture** ppCubeTexture, HANDLE* pSharedHandle, IUnknown *parent, D3DCB_CREATESURFACEFN pFn) PURE; STDMETHOD(CreateQuery)(THIS_ WINED3DQUERYTYPE Type, struct IWineD3DQuery **ppQuery, IUnknown *pParent); - STDMETHOD(CreateAdditionalSwapChain)(THIS_ WINED3DPRESENT_PARAMETERS *pPresentationParameters, struct IWineD3DSwapChain **pSwapChain, IUnknown *pParent, D3DCB_CREATERENDERTARGETFN pFn, D3DCB_CREATEDEPTHSTENCILSURFACEFN pFn2); + STDMETHOD(CreateAdditionalSwapChain)(THIS_ WINED3DPRESENT_PARAMETERS *pPresentationParameters, struct IWineD3DSwapChain **pSwapChain, IUnknown *pParent, D3DCB_CREATERENDERTARGETFN pFn, D3DCB_CREATEDEPTHSTENCILSURFACEFN pFn2, WINED3DSURFTYPE surface_type); STDMETHOD(CreateVertexDeclaration)(THIS_ struct IWineD3DVertexDeclaration** ppDecl, IUnknown* pParent, const WINED3DVERTEXELEMENT *elements, UINT element_count) PURE; STDMETHOD(CreateVertexDeclarationFromFVF)(THIS_ struct IWineD3DVertexDeclaration** ppDecl, IUnknown* pParent, DWORD Fvf) PURE; STDMETHOD(CreateVertexShader)(THIS_ struct IWineD3DVertexDeclaration *vertex_declaration, CONST DWORD* pFunction, struct IWineD3DVertexShader** ppShader, IUnknown *pParent) PURE; STDMETHOD(CreatePixelShader)(THIS_ CONST DWORD* pFunction, struct IWineD3DPixelShader** ppShader, IUnknown *pParent) PURE; STDMETHOD_(HRESULT,CreatePalette)(THIS_ DWORD Flags, PALETTEENTRY *PalEnt, struct IWineD3DPalette **Palette, IUnknown *Parent); STDMETHOD(Init3D)(THIS_ WINED3DPRESENT_PARAMETERS* pPresentationParameters, D3DCB_CREATEADDITIONALSWAPCHAIN D3DCB_CreateAdditionalSwapChain); + STDMETHOD(InitGDI)(THIS_ WINED3DPRESENT_PARAMETERS* pPresentationParameters, D3DCB_CREATEADDITIONALSWAPCHAIN D3DCB_CreateAdditionalSwapChain); STDMETHOD(Uninit3D)(THIS, D3DCB_DESTROYSURFACEFN pFn, D3DCB_DESTROYSWAPCHAINFN pFn2); + STDMETHOD(UninitGDI)(THIS, D3DCB_DESTROYSWAPCHAINFN pFn2); STDMETHOD_(void, SetFullscreen)(THIS_ BOOL fullscreen); STDMETHOD_(void, SetMultithreaded)(THIS); STDMETHOD(EvictManagedResources)(THIS) PURE; @@ -508,14 +510,16 @@ DECLARE_INTERFACE_(IWineD3DDevice,IWineD3DBase) #define IWineD3DDevice_CreateVolume(p,a,b,c,d,e,f,g,h,i) (p)->lpVtbl->CreateVolume(p,a,b,c,d,e,f,g,h,i) #define IWineD3DDevice_CreateCubeTexture(p,a,b,c,d,e,f,g,h,i) (p)->lpVtbl->CreateCubeTexture(p,a,b,c,d,e,f,g,h,i) #define IWineD3DDevice_CreateQuery(p,a,b,c) (p)->lpVtbl->CreateQuery(p,a,b,c) -#define IWineD3DDevice_CreateAdditionalSwapChain(p,a,b,c,d,e) (p)->lpVtbl->CreateAdditionalSwapChain(p,a,b,c,d,e) +#define IWineD3DDevice_CreateAdditionalSwapChain(p,a,b,c,d,e,f) (p)->lpVtbl->CreateAdditionalSwapChain(p,a,b,c,d,e,f) #define IWineD3DDevice_CreateVertexDeclaration(p,a,b,c,d) (p)->lpVtbl->CreateVertexDeclaration(p,a,b,c,d) #define IWineD3DDevice_CreateVertexDeclarationFromFVF(p,a,b,c) (p)->lpVtbl->CreateVertexDeclarationFromFVF(p,a,b,c) #define IWineD3DDevice_CreateVertexShader(p,a,b,c,d) (p)->lpVtbl->CreateVertexShader(p,a,b,c,d) #define IWineD3DDevice_CreatePixelShader(p,a,b,c) (p)->lpVtbl->CreatePixelShader(p,a,b,c) #define IWineD3DDevice_CreatePalette(p, a, b, c, d) (p)->lpVtbl->CreatePalette(p, a, b, c, d) #define IWineD3DDevice_Init3D(p, a, b) (p)->lpVtbl->Init3D(p, a, b) +#define IWineD3DDevice_InitGDI(p, a, b) (p)->lpVtbl->InitGDI(p, a, b) #define IWineD3DDevice_Uninit3D(p, a, b) (p)->lpVtbl->Uninit3D(p, a, b) +#define IWineD3DDevice_UninitGDI(p, a) (p)->lpVtbl->UninitGDI(p, a) #define IWineD3DDevice_SetFullscreen(p, a) (p)->lpVtbl->SetFullscreen(p, a) #define IWineD3DDevice_SetMultithreaded(p) (p)->lpVtbl->SetMultithreaded(p) #define IWineD3DDevice_EvictManagedResources(p) (p)->lpVtbl->EvictManagedResources(p)