From b9fcf71c714e8587def75742f94759d7eca84ad2 Mon Sep 17 00:00:00 2001 From: Henri Verbeet Date: Thu, 15 Sep 2011 20:01:51 +0200 Subject: [PATCH] ddraw: Use real flips. --- dlls/ddraw/ddraw.c | 30 +++++++++++++++++++----------- dlls/ddraw/ddraw_private.h | 4 +--- dlls/ddraw/surface.c | 25 +++++++++++++++++++++++++ dlls/wined3d/surface.c | 21 +++++++-------------- 4 files changed, 52 insertions(+), 28 deletions(-) diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c index a8b898591b7..1a639381153 100644 --- a/dlls/ddraw/ddraw.c +++ b/dlls/ddraw/ddraw.c @@ -5642,35 +5642,43 @@ static HRESULT CDECL device_parent_create_surface(struct wined3d_device_parent * return D3D_OK; } +static void STDMETHODCALLTYPE ddraw_frontbuffer_destroyed(void *parent) +{ + struct IDirectDrawImpl *ddraw = parent; + ddraw->wined3d_frontbuffer = NULL; +} + +static const struct wined3d_parent_ops ddraw_frontbuffer_parent_ops = +{ + ddraw_frontbuffer_destroyed, +}; + static HRESULT CDECL device_parent_create_rendertarget(struct wined3d_device_parent *device_parent, void *container_parent, UINT width, UINT height, enum wined3d_format_id format, WINED3DMULTISAMPLE_TYPE multisample_type, DWORD multisample_quality, BOOL lockable, struct wined3d_surface **surface) { struct IDirectDrawImpl *ddraw = ddraw_from_device_parent(device_parent); - IDirectDrawSurfaceImpl *d3d_surface = ddraw->d3d_target; + HRESULT hr; TRACE("device_parent %p, container_parent %p, width %u, height %u, format %#x, multisample_type %#x,\n" "\tmultisample_quality %u, lockable %u, surface %p.\n", device_parent, container_parent, width, height, format, multisample_type, multisample_quality, lockable, surface); - /* TODO: Return failure if the dimensions do not match, but this shouldn't - * happen. */ - - if (d3d_surface->isRenderTarget) + if (ddraw->wined3d_frontbuffer) { ERR("Frontbuffer already created.\n"); return E_FAIL; } - d3d_surface->isRenderTarget = TRUE; - - *surface = d3d_surface->wined3d_surface; - wined3d_surface_incref(*surface); - TRACE("Returning wineD3DSurface %p, it belongs to surface %p\n", *surface, d3d_surface); + hr = wined3d_surface_create(ddraw->wined3d_device, width, height, format, lockable, FALSE, 0, + WINED3DUSAGE_RENDERTARGET, WINED3DPOOL_DEFAULT, multisample_type, multisample_quality, + DefaultSurfaceType, ddraw, &ddraw_frontbuffer_parent_ops, surface); + if (SUCCEEDED(hr)) + ddraw->wined3d_frontbuffer = *surface; - return D3D_OK; + return hr; } static HRESULT CDECL device_parent_create_depth_stencil(struct wined3d_device_parent *device_parent, diff --git a/dlls/ddraw/ddraw_private.h b/dlls/ddraw/ddraw_private.h index b5d85d142ea..c1c52ca33e7 100644 --- a/dlls/ddraw/ddraw_private.h +++ b/dlls/ddraw/ddraw_private.h @@ -89,6 +89,7 @@ struct IDirectDrawImpl BOOL d3d_initialized; IDirectDrawSurfaceImpl *primary; + struct wined3d_surface *wined3d_frontbuffer; /* DirectDraw things, which are not handled by WineD3D */ DWORD cooperative_level; @@ -184,9 +185,6 @@ struct IDirectDrawSurfaceImpl DWORD uniqueness_value; UINT mipmap_level; - /* For D3DDevice creation */ - BOOL isRenderTarget; - /* Clipper objects */ IDirectDrawClipperImpl *clipper; diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c index 7357742c20f..96caa3f2757 100644 --- a/dlls/ddraw/surface.c +++ b/dlls/ddraw/surface.c @@ -39,6 +39,12 @@ static inline IDirectDrawSurfaceImpl *impl_from_IDirectDrawGammaControl(IDirectD return CONTAINING_RECORD(iface, IDirectDrawSurfaceImpl, IDirectDrawGammaControl_iface); } +static HRESULT ddraw_surface_update_frontbuffer(IDirectDrawSurfaceImpl *surface) +{ + return wined3d_surface_blt(surface->ddraw->wined3d_frontbuffer, NULL, + surface->wined3d_surface, NULL, 0, NULL, WINED3DTEXF_POINT); +} + /***************************************************************************** * IUnknown parts follow *****************************************************************************/ @@ -1072,6 +1078,8 @@ static HRESULT WINAPI ddraw_surface7_Unlock(IDirectDrawSurface7 *iface, RECT *pR hr = wined3d_surface_unmap(This->wined3d_surface); if (SUCCEEDED(hr)) { + if (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_FRONTBUFFER) + hr = ddraw_surface_update_frontbuffer(This); This->surface_desc.lpSurface = NULL; } LeaveCriticalSection(&ddraw_cs); @@ -1170,6 +1178,9 @@ static HRESULT WINAPI ddraw_surface7_Flip(IDirectDrawSurface7 *iface, IDirectDra } hr = wined3d_surface_flip(This->wined3d_surface, Override->wined3d_surface, Flags); + if (SUCCEEDED(hr) && This->surface_desc.ddsCaps.dwCaps & DDSCAPS_FRONTBUFFER) + hr = ddraw_surface_update_frontbuffer(This); + LeaveCriticalSection(&ddraw_cs); return hr; } @@ -1268,6 +1279,8 @@ static HRESULT WINAPI ddraw_surface7_Blt(IDirectDrawSurface7 *iface, RECT *DestR * struct are supported anyway. */ hr = wined3d_surface_blt(This->wined3d_surface, DestRect, Src ? Src->wined3d_surface : NULL, SrcRect, Flags, (WINEDDBLTFX *)DDBltFx, WINED3DTEXF_LINEAR); + if (SUCCEEDED(hr) && (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_FRONTBUFFER)) + hr = ddraw_surface_update_frontbuffer(This); LeaveCriticalSection(&ddraw_cs); switch(hr) @@ -1828,6 +1841,8 @@ static HRESULT WINAPI ddraw_surface7_ReleaseDC(IDirectDrawSurface7 *iface, HDC h EnterCriticalSection(&ddraw_cs); hr = wined3d_surface_releasedc(This->wined3d_surface, hdc); + if (SUCCEEDED(hr) && (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_FRONTBUFFER)) + hr = ddraw_surface_update_frontbuffer(This); LeaveCriticalSection(&ddraw_cs); return hr; } @@ -3673,6 +3688,8 @@ static HRESULT WINAPI ddraw_surface7_BltFast(IDirectDrawSurface7 *iface, DWORD d EnterCriticalSection(&ddraw_cs); hr = wined3d_surface_bltfast(This->wined3d_surface, dstx, dsty, src->wined3d_surface, rsrc, trans); + if (SUCCEEDED(hr) && (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_FRONTBUFFER)) + hr = ddraw_surface_update_frontbuffer(This); LeaveCriticalSection(&ddraw_cs); switch(hr) { @@ -4298,6 +4315,14 @@ static HRESULT WINAPI ddraw_surface7_SetPalette(IDirectDrawSurface7 *iface, IDir /* Release the old palette */ if(oldPal) IDirectDrawPalette_Release(oldPal); + /* Update the wined3d frontbuffer if this is the frontbuffer. */ + if ((This->surface_desc.ddsCaps.dwCaps & DDSCAPS_FRONTBUFFER) && This->ddraw->wined3d_frontbuffer) + { + hr = wined3d_surface_set_palette(This->ddraw->wined3d_frontbuffer, PalImpl ? PalImpl->wineD3DPalette : NULL); + if (FAILED(hr)) + ERR("Failed to set frontbuffer palette, hr %#x.\n", hr); + } + /* If this is a front buffer, also update the back buffers * TODO: How do things work for palettized cube textures? */ diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c index 22f194ae8f4..f64e0ca619b 100644 --- a/dlls/wined3d/surface.c +++ b/dlls/wined3d/surface.c @@ -3793,11 +3793,9 @@ HRESULT CDECL wined3d_surface_flip(struct wined3d_surface *surface, struct wined WARN("Ignoring flags %#x.\n", flags); } - /* FIXME: This will also prevent overlay flips, since overlays aren't on - * a swapchain either. */ - if (surface->container.type != WINED3D_CONTAINER_SWAPCHAIN) + if (surface->container.type == WINED3D_CONTAINER_SWAPCHAIN) { - ERR("Flipped surface is not on a swapchain.\n"); + ERR("Not supported on swapchain surfaces.\n"); return WINEDDERR_NOTFLIPPABLE; } @@ -3808,18 +3806,13 @@ HRESULT CDECL wined3d_surface_flip(struct wined3d_surface *surface, struct wined return WINEDDERR_NOTFLIPPABLE; } - if (surface->resource.usage & WINED3DUSAGE_OVERLAY) - { - flip_surface(surface, override); + flip_surface(surface, override); - /* Update the overlay if it is visible */ - if (surface->overlay_dest) - return surface->surface_ops->surface_draw_overlay(surface); - else - return WINED3D_OK; - } + /* Update overlays if they're visible. */ + if ((surface->resource.usage & WINED3DUSAGE_OVERLAY) && surface->overlay_dest) + return surface->surface_ops->surface_draw_overlay(surface); - return wined3d_surface_blt(surface, NULL, override, NULL, 0, NULL, WINED3DTEXF_POINT); + return WINED3D_OK; } /* Do not call while under the GL lock. */ -- 2.11.4.GIT