Module: wine Branch: master Commit: 3d49e8cd5e3872c06c5b86f8d2bb0cc41d5ddfa9 URL: http://source.winehq.org/git/wine.git/?a=commit;h=3d49e8cd5e3872c06c5b86f8d2...
Author: Stefan Dösinger stefan@codeweavers.com Date: Mon Jul 28 22:34:32 2008 -0500
wined3d: Add a swapchain method to set the dest override.
DDraw can draw to the front buffer only, thus there's never a Present call which could pass this window. Due to that a drawing-independent method is needed.
---
dlls/wined3d/swapchain.c | 73 +++++++++++++++++++++---------------- dlls/wined3d/swapchain_gdi.c | 8 ++++ include/wine/wined3d_interface.h | 2 + 3 files changed, 51 insertions(+), 32 deletions(-)
diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c index 9ec296c..1a82ab8 100644 --- a/dlls/wined3d/swapchain.c +++ b/dlls/wined3d/swapchain.c @@ -144,38 +144,7 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CO
/* Don't call checkGLcall, as glGetError is not applicable here */ if (hDestWindowOverride && This->win_handle != hDestWindowOverride) { - WINED3DLOCKED_RECT r; - BYTE *mem; - - TRACE("Performing dest override of swapchain %p from window %p to %p\n", This, This->win_handle, hDestWindowOverride); - if(This->context[0] == This->wineD3DDevice->contexts[0]) { - /* The primary context 'owns' all the opengl resources. Destroying and recreating that context requires downloading - * all opengl resources, deleting the gl resources, destroying all other contexts, then recreating all other contexts - * and reload the resources - */ - delete_opengl_contexts((IWineD3DDevice *) This->wineD3DDevice, iface); - This->win_handle = hDestWindowOverride; - create_primary_opengl_context((IWineD3DDevice *) This->wineD3DDevice, iface); - } else { - This->win_handle = hDestWindowOverride; - - /* The old back buffer has to be copied over to the new back buffer. A lockrect - switchcontext - unlockrect - * would suffice in theory, but it is rather nasty and may cause troubles with future changes of the locking code - * So lock read only, copy the surface out, then lock with the discard flag and write back - */ - IWineD3DSurface_LockRect(This->backBuffer[0], &r, NULL, WINED3DLOCK_READONLY); - mem = HeapAlloc(GetProcessHeap(), 0, r.Pitch * ((IWineD3DSurfaceImpl *) This->backBuffer[0])->currentDesc.Height); - memcpy(mem, r.pBits, r.Pitch * ((IWineD3DSurfaceImpl *) This->backBuffer[0])->currentDesc.Height); - IWineD3DSurface_UnlockRect(This->backBuffer[0]); - - DestroyContext(This->wineD3DDevice, This->context[0]); - This->context[0] = CreateContext(This->wineD3DDevice, (IWineD3DSurfaceImpl *) This->frontBuffer, This->win_handle, FALSE /* pbuffer */, &This->presentParms); - - IWineD3DSurface_LockRect(This->backBuffer[0], &r, NULL, WINED3DLOCK_DISCARD); - memcpy(r.pBits, mem, r.Pitch * ((IWineD3DSurfaceImpl *) This->backBuffer[0])->currentDesc.Height); - HeapFree(GetProcessHeap(), 0, mem); - IWineD3DSurface_UnlockRect(This->backBuffer[0]); - } + IWineD3DSwapChain_SetDestWindowOverride(iface, hDestWindowOverride); }
SwapBuffers(This->context[0]->hdc); /* TODO: cycle through the swapchain buffers */ @@ -335,6 +304,45 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CO return WINED3D_OK; }
+static HRESULT WINAPI IWineD3DSwapChainImpl_SetDestWindowOverride(IWineD3DSwapChain *iface, HWND window) { + IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface; + WINED3DLOCKED_RECT r; + BYTE *mem; + + if(window == This->win_handle) return WINED3D_OK; + + TRACE("Performing dest override of swapchain %p from window %p to %p\n", This, This->win_handle, window); + if(This->context[0] == This->wineD3DDevice->contexts[0]) { + /* The primary context 'owns' all the opengl resources. Destroying and recreating that context requires downloading + * all opengl resources, deleting the gl resources, destroying all other contexts, then recreating all other contexts + * and reload the resources + */ + delete_opengl_contexts((IWineD3DDevice *) This->wineD3DDevice, iface); + This->win_handle = window; + create_primary_opengl_context((IWineD3DDevice *) This->wineD3DDevice, iface); + } else { + This->win_handle = window; + + /* The old back buffer has to be copied over to the new back buffer. A lockrect - switchcontext - unlockrect + * would suffice in theory, but it is rather nasty and may cause troubles with future changes of the locking code + * So lock read only, copy the surface out, then lock with the discard flag and write back + */ + IWineD3DSurface_LockRect(This->backBuffer[0], &r, NULL, WINED3DLOCK_READONLY); + mem = HeapAlloc(GetProcessHeap(), 0, r.Pitch * ((IWineD3DSurfaceImpl *) This->backBuffer[0])->currentDesc.Height); + memcpy(mem, r.pBits, r.Pitch * ((IWineD3DSurfaceImpl *) This->backBuffer[0])->currentDesc.Height); + IWineD3DSurface_UnlockRect(This->backBuffer[0]); + + DestroyContext(This->wineD3DDevice, This->context[0]); + This->context[0] = CreateContext(This->wineD3DDevice, (IWineD3DSurfaceImpl *) This->frontBuffer, This->win_handle, FALSE /* pbuffer */, &This->presentParms); + + IWineD3DSurface_LockRect(This->backBuffer[0], &r, NULL, WINED3DLOCK_DISCARD); + memcpy(r.pBits, mem, r.Pitch * ((IWineD3DSurfaceImpl *) This->backBuffer[0])->currentDesc.Height); + HeapFree(GetProcessHeap(), 0, mem); + IWineD3DSurface_UnlockRect(This->backBuffer[0]); + } + return WINED3D_OK; +} + const IWineD3DSwapChainVtbl IWineD3DSwapChain_Vtbl = { /* IUnknown */ @@ -346,6 +354,7 @@ const IWineD3DSwapChainVtbl IWineD3DSwapChain_Vtbl = IWineD3DSwapChainImpl_Destroy, IWineD3DBaseSwapChainImpl_GetDevice, IWineD3DSwapChainImpl_Present, + IWineD3DSwapChainImpl_SetDestWindowOverride, IWineD3DBaseSwapChainImpl_GetFrontBufferData, IWineD3DBaseSwapChainImpl_GetBackBuffer, IWineD3DBaseSwapChainImpl_GetRasterStatus, diff --git a/dlls/wined3d/swapchain_gdi.c b/dlls/wined3d/swapchain_gdi.c index 7aa81c2..d76b9b5 100644 --- a/dlls/wined3d/swapchain_gdi.c +++ b/dlls/wined3d/swapchain_gdi.c @@ -156,6 +156,13 @@ void x11_copy_to_screen(IWineD3DSwapChainImpl *This, LPRECT rc) { } }
+static HRESULT WINAPI IWineGDISwapChainImpl_SetDestWindowOverride(IWineD3DSwapChain *iface, HWND window) { + IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface; + + This->win_handle = window; + return WINED3D_OK; +} + 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; @@ -254,6 +261,7 @@ const IWineD3DSwapChainVtbl IWineGDISwapChain_Vtbl = IWineGDISwapChainImpl_Destroy, IWineD3DBaseSwapChainImpl_GetDevice, IWineGDISwapChainImpl_Present, + IWineGDISwapChainImpl_SetDestWindowOverride, IWineD3DBaseSwapChainImpl_GetFrontBufferData, IWineD3DBaseSwapChainImpl_GetBackBuffer, IWineD3DBaseSwapChainImpl_GetRasterStatus, diff --git a/include/wine/wined3d_interface.h b/include/wine/wined3d_interface.h index 0768b0a..d2c8a2c 100644 --- a/include/wine/wined3d_interface.h +++ b/include/wine/wined3d_interface.h @@ -1421,6 +1421,7 @@ DECLARE_INTERFACE_(IWineD3DSwapChain,IWineD3DBase) STDMETHOD_(void, Destroy)(THIS_ D3DCB_DESTROYSURFACEFN pFn) PURE; STDMETHOD(GetDevice)(THIS_ IWineD3DDevice **ppDevice) PURE; STDMETHOD(Present)(THIS_ CONST RECT *pSourceRect, CONST RECT *pDestRect, HWND hDestWindowOverride, CONST RGNDATA *pDirtyRegion, DWORD dwFlags) PURE; + STDMETHOD(SetDestWindowOverride)(THIS_ HWND window); STDMETHOD(GetFrontBufferData)(THIS_ IWineD3DSurface *pDestSurface) PURE; STDMETHOD(GetBackBuffer)(THIS_ UINT iBackBuffer, WINED3DBACKBUFFER_TYPE Type, IWineD3DSurface **ppBackBuffer) PURE; STDMETHOD(GetRasterStatus)(THIS_ WINED3DRASTER_STATUS *pRasterStatus) PURE; @@ -1442,6 +1443,7 @@ DECLARE_INTERFACE_(IWineD3DSwapChain,IWineD3DBase) #define IWineD3DSwapChain_Destroy(p,a) (p)->lpVtbl->Destroy(p,a) #define IWineD3DSwapChain_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a) #define IWineD3DSwapChain_Present(p,a,b,c,d,e) (p)->lpVtbl->Present(p,a,b,c,d,e) +#define IWineD3DSwapChain_SetDestWindowOverride(p,a) (p)->lpVtbl->SetDestWindowOverride(p,a) #define IWineD3DSwapChain_GetFrontBufferData(p,a) (p)->lpVtbl->GetFrontBufferData(p,a) #define IWineD3DSwapChain_GetBackBuffer(p,a,b,c) (p)->lpVtbl->GetBackBuffer(p,a,b,c) #define IWineD3DSwapChain_GetRasterStatus(p,a) (p)->lpVtbl->GetRasterStatus(p,a)