[PATCH 3/5] ddraw: Validate that surfaces are on the same swap chain in ddraw_surface7_Flip().
Henri Verbeet
hverbeet at codeweavers.com
Wed Dec 4 02:49:35 CST 2013
---
dlls/ddraw/surface.c | 73 ++++++++++++++++++++-------------------------
dlls/ddraw/tests/ddraw1.c | 2 +-
dlls/ddraw/tests/ddraw2.c | 2 +-
dlls/ddraw/tests/ddraw4.c | 2 +-
dlls/ddraw/tests/ddraw7.c | 2 +-
5 files changed, 37 insertions(+), 44 deletions(-)
diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c
index 477ef4f..9d570e4 100644
--- a/dlls/ddraw/surface.c
+++ b/dlls/ddraw/surface.c
@@ -1170,62 +1170,55 @@ static HRESULT WINAPI ddraw_surface1_Unlock(IDirectDrawSurface *iface, void *dat
return ddraw_surface7_Unlock(&surface->IDirectDrawSurface7_iface, NULL);
}
-/*****************************************************************************
- * IDirectDrawSurface7::Flip
- *
- * Flips a surface with the DDSCAPS_FLIP flag. The flip is relayed to
- * IWineD3DSurface::Flip. Because WineD3D doesn't handle attached surfaces,
- * the flip target is passed to WineD3D, even if the app didn't specify one
- *
- * Params:
- * DestOverride: Specifies the surface that will become the new front
- * buffer. If NULL, the current back buffer is used
- * Flags: some DirectDraw flags, see include/ddraw.h
- *
- * Returns:
- * DD_OK on success
- * DDERR_NOTFLIPPABLE if no flip target could be found
- * DDERR_INVALIDOBJECT if the surface isn't a front buffer
- * For more details, see IWineD3DSurface::Flip
- *
- *****************************************************************************/
-static HRESULT WINAPI ddraw_surface7_Flip(IDirectDrawSurface7 *iface, IDirectDrawSurface7 *DestOverride, DWORD Flags)
+static HRESULT WINAPI ddraw_surface7_Flip(IDirectDrawSurface7 *iface, IDirectDrawSurface7 *src, DWORD flags)
{
- struct ddraw_surface *surface = impl_from_IDirectDrawSurface7(iface);
- struct ddraw_surface *Override = unsafe_impl_from_IDirectDrawSurface7(DestOverride);
- IDirectDrawSurface7 *Override7;
+ struct ddraw_surface *dst_impl = impl_from_IDirectDrawSurface7(iface);
+ struct ddraw_surface *src_impl = unsafe_impl_from_IDirectDrawSurface7(src);
+ DDSCAPS2 caps = {DDSCAPS_FLIP, 0, 0, 0};
+ IDirectDrawSurface7 *current;
HRESULT hr;
- TRACE("iface %p, dst %p, flags %#x.\n", iface, DestOverride, Flags);
+ TRACE("iface %p, src %p, flags %#x.\n", iface, src, flags);
- if (DestOverride == iface || !(surface->surface_desc.ddsCaps.dwCaps & (DDSCAPS_FRONTBUFFER | DDSCAPS_OVERLAY)))
+ if (src == iface || !(dst_impl->surface_desc.ddsCaps.dwCaps & (DDSCAPS_FRONTBUFFER | DDSCAPS_OVERLAY)))
return DDERR_NOTFLIPPABLE;
wined3d_mutex_lock();
- /* WineD3D doesn't keep track of attached surface, so find the target */
- if(!Override)
+ if (src_impl)
{
- DDSCAPS2 Caps;
-
- memset(&Caps, 0, sizeof(Caps));
- Caps.dwCaps |= DDSCAPS_BACKBUFFER;
- hr = ddraw_surface7_GetAttachedSurface(iface, &Caps, &Override7);
- if(hr != DD_OK)
+ for (current = iface; current != src;)
+ {
+ if (FAILED(hr = ddraw_surface7_GetAttachedSurface(current, &caps, ¤t)))
+ {
+ WARN("Surface %p is not on the same flip chain as surface %p.\n", src, iface);
+ wined3d_mutex_unlock();
+ return DDERR_NOTFLIPPABLE;
+ }
+ ddraw_surface7_Release(current);
+ if (current == iface)
+ {
+ WARN("Surface %p is not on the same flip chain as surface %p.\n", src, iface);
+ wined3d_mutex_unlock();
+ return DDERR_NOTFLIPPABLE;
+ }
+ }
+ }
+ else
+ {
+ if (FAILED(hr = ddraw_surface7_GetAttachedSurface(iface, &caps, ¤t)))
{
ERR("Can't find a flip target\n");
wined3d_mutex_unlock();
return DDERR_NOTFLIPPABLE; /* Unchecked */
}
- Override = impl_from_IDirectDrawSurface7(Override7);
-
- /* For the GetAttachedSurface */
- ddraw_surface7_Release(Override7);
+ src_impl = impl_from_IDirectDrawSurface7(current);
+ ddraw_surface7_Release(current);
}
- hr = wined3d_surface_flip(surface->wined3d_surface, Override->wined3d_surface, Flags);
- if (SUCCEEDED(hr) && surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
- hr = ddraw_surface_update_frontbuffer(surface, NULL, FALSE);
+ if (SUCCEEDED(hr = wined3d_surface_flip(dst_impl->wined3d_surface, src_impl->wined3d_surface, flags))
+ && (dst_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE))
+ hr = ddraw_surface_update_frontbuffer(dst_impl, NULL, FALSE);
wined3d_mutex_unlock();
diff --git a/dlls/ddraw/tests/ddraw1.c b/dlls/ddraw/tests/ddraw1.c
index c8d60fe..46e1239 100644
--- a/dlls/ddraw/tests/ddraw1.c
+++ b/dlls/ddraw/tests/ddraw1.c
@@ -3618,7 +3618,7 @@ static void test_flip(void)
hr = IDirectDraw_CreateSurface(ddraw, &surface_desc, &surface, NULL);
ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
hr = IDirectDrawSurface_Flip(primary, surface, DDFLIP_WAIT);
- todo_wine ok(hr == DDERR_NOTFLIPPABLE, "Got unexpected hr %#x.\n", hr);
+ ok(hr == DDERR_NOTFLIPPABLE, "Got unexpected hr %#x.\n", hr);
IDirectDrawSurface_Release(surface);
hr = IDirectDrawSurface_Flip(primary, primary, DDFLIP_WAIT);
diff --git a/dlls/ddraw/tests/ddraw2.c b/dlls/ddraw/tests/ddraw2.c
index 34559cc..80c86ff 100644
--- a/dlls/ddraw/tests/ddraw2.c
+++ b/dlls/ddraw/tests/ddraw2.c
@@ -4299,7 +4299,7 @@ static void test_flip(void)
hr = IDirectDraw2_CreateSurface(ddraw, &surface_desc, &surface, NULL);
ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
hr = IDirectDrawSurface_Flip(primary, surface, DDFLIP_WAIT);
- todo_wine ok(hr == DDERR_NOTFLIPPABLE, "Got unexpected hr %#x.\n", hr);
+ ok(hr == DDERR_NOTFLIPPABLE, "Got unexpected hr %#x.\n", hr);
IDirectDrawSurface_Release(surface);
hr = IDirectDrawSurface_Flip(primary, primary, DDFLIP_WAIT);
diff --git a/dlls/ddraw/tests/ddraw4.c b/dlls/ddraw/tests/ddraw4.c
index 865dc0f..489dfe7 100644
--- a/dlls/ddraw/tests/ddraw4.c
+++ b/dlls/ddraw/tests/ddraw4.c
@@ -4903,7 +4903,7 @@ static void test_flip(void)
hr = IDirectDraw4_CreateSurface(ddraw, &surface_desc, &surface, NULL);
ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
hr = IDirectDrawSurface4_Flip(primary, surface, DDFLIP_WAIT);
- todo_wine ok(hr == DDERR_NOTFLIPPABLE, "Got unexpected hr %#x.\n", hr);
+ ok(hr == DDERR_NOTFLIPPABLE, "Got unexpected hr %#x.\n", hr);
IDirectDrawSurface4_Release(surface);
hr = IDirectDrawSurface4_Flip(primary, primary, DDFLIP_WAIT);
diff --git a/dlls/ddraw/tests/ddraw7.c b/dlls/ddraw/tests/ddraw7.c
index 050d303..8818828 100644
--- a/dlls/ddraw/tests/ddraw7.c
+++ b/dlls/ddraw/tests/ddraw7.c
@@ -4790,7 +4790,7 @@ static void test_flip(void)
hr = IDirectDraw7_CreateSurface(ddraw, &surface_desc, &surface, NULL);
ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
hr = IDirectDrawSurface7_Flip(primary, surface, DDFLIP_WAIT);
- todo_wine ok(hr == DDERR_NOTFLIPPABLE, "Got unexpected hr %#x.\n", hr);
+ ok(hr == DDERR_NOTFLIPPABLE, "Got unexpected hr %#x.\n", hr);
IDirectDrawSurface7_Release(surface);
hr = IDirectDrawSurface7_Flip(primary, primary, DDFLIP_WAIT);
--
1.7.10.4
More information about the wine-patches
mailing list