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