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.
This commit is contained in:
parent
66738fbb87
commit
e178ddd9e1
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
*
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -30,6 +30,7 @@ C_SRCS = \
|
|||
surface.c \
|
||||
surface_gdi.c \
|
||||
swapchain.c \
|
||||
swapchain_gdi.c \
|
||||
swapchain_base.c \
|
||||
texture.c \
|
||||
utils.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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
};
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue