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.
This commit is contained in:
parent
25c07dc86c
commit
3d49e8cd5e
|
@ -144,38 +144,7 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CO
|
||||||
|
|
||||||
/* Don't call checkGLcall, as glGetError is not applicable here */
|
/* Don't call checkGLcall, as glGetError is not applicable here */
|
||||||
if (hDestWindowOverride && This->win_handle != hDestWindowOverride) {
|
if (hDestWindowOverride && This->win_handle != hDestWindowOverride) {
|
||||||
WINED3DLOCKED_RECT r;
|
IWineD3DSwapChain_SetDestWindowOverride(iface, hDestWindowOverride);
|
||||||
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]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SwapBuffers(This->context[0]->hdc); /* TODO: cycle through the swapchain buffers */
|
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;
|
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 =
|
const IWineD3DSwapChainVtbl IWineD3DSwapChain_Vtbl =
|
||||||
{
|
{
|
||||||
/* IUnknown */
|
/* IUnknown */
|
||||||
|
@ -346,6 +354,7 @@ const IWineD3DSwapChainVtbl IWineD3DSwapChain_Vtbl =
|
||||||
IWineD3DSwapChainImpl_Destroy,
|
IWineD3DSwapChainImpl_Destroy,
|
||||||
IWineD3DBaseSwapChainImpl_GetDevice,
|
IWineD3DBaseSwapChainImpl_GetDevice,
|
||||||
IWineD3DSwapChainImpl_Present,
|
IWineD3DSwapChainImpl_Present,
|
||||||
|
IWineD3DSwapChainImpl_SetDestWindowOverride,
|
||||||
IWineD3DBaseSwapChainImpl_GetFrontBufferData,
|
IWineD3DBaseSwapChainImpl_GetFrontBufferData,
|
||||||
IWineD3DBaseSwapChainImpl_GetBackBuffer,
|
IWineD3DBaseSwapChainImpl_GetBackBuffer,
|
||||||
IWineD3DBaseSwapChainImpl_GetRasterStatus,
|
IWineD3DBaseSwapChainImpl_GetRasterStatus,
|
||||||
|
|
|
@ -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) {
|
static HRESULT WINAPI IWineGDISwapChainImpl_Present(IWineD3DSwapChain *iface, CONST RECT *pSourceRect, CONST RECT *pDestRect, HWND hDestWindowOverride, CONST RGNDATA *pDirtyRegion, DWORD dwFlags) {
|
||||||
IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *) iface;
|
IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *) iface;
|
||||||
IWineD3DSurfaceImpl *front, *back;
|
IWineD3DSurfaceImpl *front, *back;
|
||||||
|
@ -254,6 +261,7 @@ const IWineD3DSwapChainVtbl IWineGDISwapChain_Vtbl =
|
||||||
IWineGDISwapChainImpl_Destroy,
|
IWineGDISwapChainImpl_Destroy,
|
||||||
IWineD3DBaseSwapChainImpl_GetDevice,
|
IWineD3DBaseSwapChainImpl_GetDevice,
|
||||||
IWineGDISwapChainImpl_Present,
|
IWineGDISwapChainImpl_Present,
|
||||||
|
IWineGDISwapChainImpl_SetDestWindowOverride,
|
||||||
IWineD3DBaseSwapChainImpl_GetFrontBufferData,
|
IWineD3DBaseSwapChainImpl_GetFrontBufferData,
|
||||||
IWineD3DBaseSwapChainImpl_GetBackBuffer,
|
IWineD3DBaseSwapChainImpl_GetBackBuffer,
|
||||||
IWineD3DBaseSwapChainImpl_GetRasterStatus,
|
IWineD3DBaseSwapChainImpl_GetRasterStatus,
|
||||||
|
|
|
@ -1421,6 +1421,7 @@ DECLARE_INTERFACE_(IWineD3DSwapChain,IWineD3DBase)
|
||||||
STDMETHOD_(void, Destroy)(THIS_ D3DCB_DESTROYSURFACEFN pFn) PURE;
|
STDMETHOD_(void, Destroy)(THIS_ D3DCB_DESTROYSURFACEFN pFn) PURE;
|
||||||
STDMETHOD(GetDevice)(THIS_ IWineD3DDevice **ppDevice) 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(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(GetFrontBufferData)(THIS_ IWineD3DSurface *pDestSurface) PURE;
|
||||||
STDMETHOD(GetBackBuffer)(THIS_ UINT iBackBuffer, WINED3DBACKBUFFER_TYPE Type, IWineD3DSurface **ppBackBuffer) PURE;
|
STDMETHOD(GetBackBuffer)(THIS_ UINT iBackBuffer, WINED3DBACKBUFFER_TYPE Type, IWineD3DSurface **ppBackBuffer) PURE;
|
||||||
STDMETHOD(GetRasterStatus)(THIS_ WINED3DRASTER_STATUS *pRasterStatus) 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_Destroy(p,a) (p)->lpVtbl->Destroy(p,a)
|
||||||
#define IWineD3DSwapChain_GetDevice(p,a) (p)->lpVtbl->GetDevice(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_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_GetFrontBufferData(p,a) (p)->lpVtbl->GetFrontBufferData(p,a)
|
||||||
#define IWineD3DSwapChain_GetBackBuffer(p,a,b,c) (p)->lpVtbl->GetBackBuffer(p,a,b,c)
|
#define IWineD3DSwapChain_GetBackBuffer(p,a,b,c) (p)->lpVtbl->GetBackBuffer(p,a,b,c)
|
||||||
#define IWineD3DSwapChain_GetRasterStatus(p,a) (p)->lpVtbl->GetRasterStatus(p,a)
|
#define IWineD3DSwapChain_GetRasterStatus(p,a) (p)->lpVtbl->GetRasterStatus(p,a)
|
||||||
|
|
Loading…
Reference in New Issue