[PATCH 2/3] ddraw: Mark surfaces as lost when the device window is deactivated.

Henri Verbeet hverbeet at codeweavers.com
Fri Dec 4 04:30:14 CST 2015


Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
---
 dlls/ddraw/ddraw.c             | 23 ++++++++++++++++++++---
 dlls/ddraw/ddraw_private.h     |  3 +++
 dlls/ddraw/surface.c           | 23 ++++++-----------------
 dlls/ddraw/tests/ddraw1.c      |  8 ++++----
 dlls/ddraw/tests/ddraw2.c      |  8 ++++----
 dlls/ddraw/tests/ddraw4.c      |  8 ++++----
 dlls/ddraw/tests/ddraw7.c      |  8 ++++----
 dlls/wined3d/surface.c         | 25 +------------------------
 dlls/wined3d/wined3d.spec      |  2 --
 dlls/wined3d/wined3d_private.h |  1 -
 include/wine/wined3d.h         |  3 ---
 11 files changed, 46 insertions(+), 66 deletions(-)

diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c
index e521734..ce7bef8 100644
--- a/dlls/ddraw/ddraw.c
+++ b/dlls/ddraw/ddraw.c
@@ -927,6 +927,7 @@ static HRESULT ddraw_set_cooperative_level(struct ddraw *ddraw, HWND window,
                 wined3d_rendertarget_view_incref(dsv);
         }
 
+        ddraw->device_state = DDRAW_DEVICE_STATE_NOT_RESTORED;
         ddraw_destroy_swapchain(ddraw);
     }
 
@@ -2183,7 +2184,7 @@ static HRESULT WINAPI ddraw7_TestCooperativeLevel(IDirectDraw7 *iface)
 
     TRACE("iface %p.\n", iface);
 
-    return ddraw->device_state == DDRAW_DEVICE_STATE_OK ? DD_OK : DDERR_NOEXCLUSIVEMODE;
+    return ddraw->device_state == DDRAW_DEVICE_STATE_LOST ? DDERR_NOEXCLUSIVEMODE : DD_OK;
 }
 
 static HRESULT WINAPI ddraw4_TestCooperativeLevel(IDirectDraw4 *iface)
@@ -4706,9 +4707,23 @@ static void CDECL device_parent_activate(struct wined3d_device_parent *device_pa
     TRACE("device_parent %p, activate %#x.\n", device_parent, activate);
 
     if (!activate)
-        InterlockedCompareExchange(&ddraw->device_state, DDRAW_DEVICE_STATE_LOST, DDRAW_DEVICE_STATE_OK);
+        ddraw->device_state = DDRAW_DEVICE_STATE_LOST;
     else
-        InterlockedCompareExchange(&ddraw->device_state, DDRAW_DEVICE_STATE_OK, DDRAW_DEVICE_STATE_LOST);
+        InterlockedCompareExchange(&ddraw->device_state, DDRAW_DEVICE_STATE_NOT_RESTORED, DDRAW_DEVICE_STATE_LOST);
+}
+
+void ddraw_update_lost_surfaces(struct ddraw *ddraw)
+{
+    struct ddraw_surface *surface;
+
+    if (ddraw->device_state != DDRAW_DEVICE_STATE_NOT_RESTORED)
+        return;
+
+    LIST_FOR_EACH_ENTRY(surface, &ddraw->surface_list, struct ddraw_surface, surface_list_entry)
+    {
+        surface->is_lost = TRUE;
+    }
+    ddraw->device_state = DDRAW_DEVICE_STATE_OK;
 }
 
 static HRESULT CDECL device_parent_surface_created(struct wined3d_device_parent *device_parent,
@@ -4738,6 +4753,8 @@ static HRESULT CDECL device_parent_surface_created(struct wined3d_device_parent
 
     ddraw_surface_init(ddraw_surface, ddraw, wined3d_texture_get_parent(wined3d_texture), surface, parent_ops);
     *parent = ddraw_surface;
+
+    ddraw_update_lost_surfaces(ddraw);
     list_add_head(&ddraw->surface_list, &ddraw_surface->surface_list_entry);
 
     TRACE("Created ddraw surface %p.\n", ddraw_surface);
diff --git a/dlls/ddraw/ddraw_private.h b/dlls/ddraw/ddraw_private.h
index 7c50031..38139f8 100644
--- a/dlls/ddraw/ddraw_private.h
+++ b/dlls/ddraw/ddraw_private.h
@@ -66,6 +66,7 @@ enum ddraw_device_state
 {
     DDRAW_DEVICE_STATE_OK,
     DDRAW_DEVICE_STATE_LOST,
+    DDRAW_DEVICE_STATE_NOT_RESTORED,
 };
 
 struct ddraw
@@ -126,6 +127,7 @@ HRESULT ddraw_init(struct ddraw *ddraw, DWORD flags, enum wined3d_device_type de
 void ddraw_d3dcaps1_from_7(D3DDEVICEDESC *caps1, D3DDEVICEDESC7 *caps7) DECLSPEC_HIDDEN;
 void ddraw_destroy_swapchain(struct ddraw *ddraw) DECLSPEC_HIDDEN;
 HRESULT ddraw_get_d3dcaps(const struct ddraw *ddraw, D3DDEVICEDESC7 *caps) DECLSPEC_HIDDEN;
+void ddraw_update_lost_surfaces(struct ddraw *ddraw) DECLSPEC_HIDDEN;
 
 static inline void ddraw_set_swapchain_window(struct ddraw *ddraw, HWND window)
 {
@@ -181,6 +183,7 @@ struct ddraw_surface
      * but no pointer to prevent temptations to traverse it in the wrong direction.
      */
     BOOL                    is_complex_root;
+    BOOL is_lost;
 
     /* Surface description, for GetAttachedSurface */
     DDSURFACEDESC2          surface_desc;
diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c
index f8acb2d..c303ed0 100644
--- a/dlls/ddraw/surface.c
+++ b/dlls/ddraw/surface.c
@@ -3507,22 +3507,13 @@ static HRESULT WINAPI d3d_texture1_Initialize(IDirect3DTexture *iface,
 static HRESULT WINAPI ddraw_surface7_IsLost(IDirectDrawSurface7 *iface)
 {
     struct ddraw_surface *surface = impl_from_IDirectDrawSurface7(iface);
-    HRESULT hr;
 
     TRACE("iface %p.\n", iface);
 
-    wined3d_mutex_lock();
-    hr = wined3d_surface_is_lost(surface->wined3d_surface);
-    wined3d_mutex_unlock();
+    if (surface->ddraw->device_state != DDRAW_DEVICE_STATE_OK || surface->is_lost)
+        return DDERR_SURFACELOST;
 
-    switch(hr)
-    {
-        /* D3D8 and 9 lose full devices, thus there's only a DEVICELOST error.
-         * WineD3D uses the same error for surfaces
-         */
-        case WINED3DERR_DEVICELOST:         return DDERR_SURFACELOST;
-        default:                            return hr;
-    }
+    return DD_OK;
 }
 
 static HRESULT WINAPI ddraw_surface4_IsLost(IDirectDrawSurface4 *iface)
@@ -3575,15 +3566,13 @@ static HRESULT WINAPI ddraw_surface1_IsLost(IDirectDrawSurface *iface)
 static HRESULT WINAPI ddraw_surface7_Restore(IDirectDrawSurface7 *iface)
 {
     struct ddraw_surface *surface = impl_from_IDirectDrawSurface7(iface);
-    HRESULT hr;
 
     TRACE("iface %p.\n", iface);
 
-    wined3d_mutex_lock();
-    hr = wined3d_surface_restore(surface->wined3d_surface);
-    wined3d_mutex_unlock();
+    ddraw_update_lost_surfaces(surface->ddraw);
+    surface->is_lost = FALSE;
 
-    return hr;
+    return DD_OK;
 }
 
 static HRESULT WINAPI ddraw_surface4_Restore(IDirectDrawSurface4 *iface)
diff --git a/dlls/ddraw/tests/ddraw1.c b/dlls/ddraw/tests/ddraw1.c
index 4b99dd0..f5122b6 100644
--- a/dlls/ddraw/tests/ddraw1.c
+++ b/dlls/ddraw/tests/ddraw1.c
@@ -6187,16 +6187,16 @@ static void test_lost_device(void)
     ret = SetForegroundWindow(GetDesktopWindow());
     ok(ret, "Failed to set foreground window.\n");
     hr = IDirectDrawSurface_IsLost(surface);
-    todo_wine ok(hr == DDERR_SURFACELOST, "Got unexpected hr %#x.\n", hr);
+    ok(hr == DDERR_SURFACELOST, "Got unexpected hr %#x.\n", hr);
     hr = IDirectDrawSurface_Flip(surface, NULL, DDFLIP_WAIT);
-    todo_wine ok(hr == DDERR_SURFACELOST, "Got unexpected hr %#x.\n", hr);
+    ok(hr == DDERR_SURFACELOST, "Got unexpected hr %#x.\n", hr);
 
     ret = SetForegroundWindow(window);
     ok(ret, "Failed to set foreground window.\n");
     hr = IDirectDrawSurface_IsLost(surface);
-    todo_wine ok(hr == DDERR_SURFACELOST, "Got unexpected hr %#x.\n", hr);
+    ok(hr == DDERR_SURFACELOST, "Got unexpected hr %#x.\n", hr);
     hr = IDirectDrawSurface_Flip(surface, NULL, DDFLIP_WAIT);
-    todo_wine ok(hr == DDERR_SURFACELOST, "Got unexpected hr %#x.\n", hr);
+    ok(hr == DDERR_SURFACELOST, "Got unexpected hr %#x.\n", hr);
 
     hr = restore_surfaces(ddraw);
     ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
diff --git a/dlls/ddraw/tests/ddraw2.c b/dlls/ddraw/tests/ddraw2.c
index 20a342f..177f3ec 100644
--- a/dlls/ddraw/tests/ddraw2.c
+++ b/dlls/ddraw/tests/ddraw2.c
@@ -7434,16 +7434,16 @@ static void test_lost_device(void)
     ret = SetForegroundWindow(GetDesktopWindow());
     ok(ret, "Failed to set foreground window.\n");
     hr = IDirectDrawSurface_IsLost(surface);
-    todo_wine ok(hr == DDERR_SURFACELOST, "Got unexpected hr %#x.\n", hr);
+    ok(hr == DDERR_SURFACELOST, "Got unexpected hr %#x.\n", hr);
     hr = IDirectDrawSurface_Flip(surface, NULL, DDFLIP_WAIT);
-    todo_wine ok(hr == DDERR_SURFACELOST, "Got unexpected hr %#x.\n", hr);
+    ok(hr == DDERR_SURFACELOST, "Got unexpected hr %#x.\n", hr);
 
     ret = SetForegroundWindow(window);
     ok(ret, "Failed to set foreground window.\n");
     hr = IDirectDrawSurface_IsLost(surface);
-    todo_wine ok(hr == DDERR_SURFACELOST, "Got unexpected hr %#x.\n", hr);
+    ok(hr == DDERR_SURFACELOST, "Got unexpected hr %#x.\n", hr);
     hr = IDirectDrawSurface_Flip(surface, NULL, DDFLIP_WAIT);
-    todo_wine ok(hr == DDERR_SURFACELOST, "Got unexpected hr %#x.\n", hr);
+    ok(hr == DDERR_SURFACELOST, "Got unexpected hr %#x.\n", hr);
 
     hr = restore_surfaces(ddraw);
     ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
diff --git a/dlls/ddraw/tests/ddraw4.c b/dlls/ddraw/tests/ddraw4.c
index 20cd989..c521e51 100644
--- a/dlls/ddraw/tests/ddraw4.c
+++ b/dlls/ddraw/tests/ddraw4.c
@@ -8497,18 +8497,18 @@ static void test_lost_device(void)
     hr = IDirectDraw4_TestCooperativeLevel(ddraw);
     ok(hr == DDERR_NOEXCLUSIVEMODE, "Got unexpected hr %#x.\n", hr);
     hr = IDirectDrawSurface4_IsLost(surface);
-    todo_wine ok(hr == DDERR_SURFACELOST, "Got unexpected hr %#x.\n", hr);
+    ok(hr == DDERR_SURFACELOST, "Got unexpected hr %#x.\n", hr);
     hr = IDirectDrawSurface4_Flip(surface, NULL, DDFLIP_WAIT);
-    todo_wine ok(hr == DDERR_SURFACELOST, "Got unexpected hr %#x.\n", hr);
+    ok(hr == DDERR_SURFACELOST, "Got unexpected hr %#x.\n", hr);
 
     ret = SetForegroundWindow(window);
     ok(ret, "Failed to set foreground window.\n");
     hr = IDirectDraw4_TestCooperativeLevel(ddraw);
     ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
     hr = IDirectDrawSurface4_IsLost(surface);
-    todo_wine ok(hr == DDERR_SURFACELOST, "Got unexpected hr %#x.\n", hr);
+    ok(hr == DDERR_SURFACELOST, "Got unexpected hr %#x.\n", hr);
     hr = IDirectDrawSurface4_Flip(surface, NULL, DDFLIP_WAIT);
-    todo_wine ok(hr == DDERR_SURFACELOST, "Got unexpected hr %#x.\n", hr);
+    ok(hr == DDERR_SURFACELOST, "Got unexpected hr %#x.\n", hr);
 
     hr = IDirectDraw4_RestoreAllSurfaces(ddraw);
     ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
diff --git a/dlls/ddraw/tests/ddraw7.c b/dlls/ddraw/tests/ddraw7.c
index 8ab0972..57cec09 100644
--- a/dlls/ddraw/tests/ddraw7.c
+++ b/dlls/ddraw/tests/ddraw7.c
@@ -8247,18 +8247,18 @@ static void test_lost_device(void)
     hr = IDirectDraw7_TestCooperativeLevel(ddraw);
     ok(hr == DDERR_NOEXCLUSIVEMODE, "Got unexpected hr %#x.\n", hr);
     hr = IDirectDrawSurface7_IsLost(surface);
-    todo_wine ok(hr == DDERR_SURFACELOST, "Got unexpected hr %#x.\n", hr);
+    ok(hr == DDERR_SURFACELOST, "Got unexpected hr %#x.\n", hr);
     hr = IDirectDrawSurface7_Flip(surface, NULL, DDFLIP_WAIT);
-    todo_wine ok(hr == DDERR_SURFACELOST, "Got unexpected hr %#x.\n", hr);
+    ok(hr == DDERR_SURFACELOST, "Got unexpected hr %#x.\n", hr);
 
     ret = SetForegroundWindow(window);
     ok(ret, "Failed to set foreground window.\n");
     hr = IDirectDraw7_TestCooperativeLevel(ddraw);
     ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
     hr = IDirectDrawSurface7_IsLost(surface);
-    todo_wine ok(hr == DDERR_SURFACELOST, "Got unexpected hr %#x.\n", hr);
+    ok(hr == DDERR_SURFACELOST, "Got unexpected hr %#x.\n", hr);
     hr = IDirectDrawSurface7_Flip(surface, NULL, DDFLIP_WAIT);
-    todo_wine ok(hr == DDERR_SURFACELOST, "Got unexpected hr %#x.\n", hr);
+    ok(hr == DDERR_SURFACELOST, "Got unexpected hr %#x.\n", hr);
 
     hr = IDirectDraw7_RestoreAllSurfaces(ddraw);
     ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index a8f7179..29687c3 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -1161,12 +1161,6 @@ static void surface_unload(struct wined3d_resource *resource)
             surface_validate_location(surface, WINED3D_LOCATION_SYSMEM);
             surface_invalidate_location(surface, ~WINED3D_LOCATION_SYSMEM);
         }
-
-        /* We also get here when the ddraw swapchain is destroyed, for example
-         * for a mode switch. In this case this surface won't necessarily be
-         * an implicit surface. We have to mark it lost so that the
-         * application can restore it after the mode switch. */
-        surface->flags |= SFLAG_LOST;
     }
     else
     {
@@ -1924,22 +1918,6 @@ struct wined3d_resource * CDECL wined3d_surface_get_resource(struct wined3d_surf
     return &surface->resource;
 }
 
-HRESULT CDECL wined3d_surface_is_lost(const struct wined3d_surface *surface)
-{
-    TRACE("surface %p.\n", surface);
-
-    /* D3D8 and 9 lose full devices, ddraw only surfaces. */
-    return surface->flags & SFLAG_LOST ? WINED3DERR_DEVICELOST : WINED3D_OK;
-}
-
-HRESULT CDECL wined3d_surface_restore(struct wined3d_surface *surface)
-{
-    TRACE("surface %p.\n", surface);
-
-    surface->flags &= ~SFLAG_LOST;
-    return WINED3D_OK;
-}
-
 DWORD CDECL wined3d_surface_get_pitch(const struct wined3d_surface *surface)
 {
     unsigned int alignment;
@@ -4157,8 +4135,7 @@ HRESULT surface_load_location(struct wined3d_surface *surface, struct wined3d_co
     if (!surface->locations)
     {
         ERR("Surface %p does not have any up to date location.\n", surface);
-        surface->flags |= SFLAG_LOST;
-        return WINED3DERR_DEVICELOST;
+        return WINED3DERR_INVALIDCALL;
     }
 
     switch (location)
diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec
index 7df80fb..c09e0a6 100644
--- a/dlls/wined3d/wined3d.spec
+++ b/dlls/wined3d/wined3d.spec
@@ -231,11 +231,9 @@
 @ cdecl wined3d_surface_get_resource(ptr)
 @ cdecl wined3d_surface_getdc(ptr ptr)
 @ cdecl wined3d_surface_incref(ptr)
-@ cdecl wined3d_surface_is_lost(ptr)
 @ cdecl wined3d_surface_map(ptr ptr ptr long)
 @ cdecl wined3d_surface_preload(ptr)
 @ cdecl wined3d_surface_releasedc(ptr ptr)
-@ cdecl wined3d_surface_restore(ptr)
 @ cdecl wined3d_surface_set_overlay_position(ptr long long)
 @ cdecl wined3d_surface_unmap(ptr)
 @ cdecl wined3d_surface_update_overlay(ptr ptr ptr ptr long ptr)
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 6819330..abe1262 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -2492,7 +2492,6 @@ void draw_textured_quad(const struct wined3d_surface *src_surface, struct wined3
 #define SFLAG_DIBSECTION        0x00000001 /* Has a DIB section attached for GetDC. */
 #define SFLAG_DISCARD           0x00000002 /* ??? */
 #define SFLAG_NONPOW2           0x00000004 /* Surface sizes are not a power of 2 */
-#define SFLAG_LOST              0x00000008 /* Surface lost flag for ddraw. */
 #define SFLAG_CLIENT            0x00000010 /* GL_APPLE_client_storage is used with this surface. */
 #define SFLAG_DCINUSE           0x00000020 /* Set between GetDC and ReleaseDC calls. */
 
diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h
index 8b29aba..e38bc7d 100644
--- a/include/wine/wined3d.h
+++ b/include/wine/wined3d.h
@@ -53,7 +53,6 @@
 #define WINED3DERR_DRIVERINTERNALERROR                          MAKE_WINED3DHRESULT(2087)
 #define WINED3DERR_NOTFOUND                                     MAKE_WINED3DHRESULT(2150)
 #define WINED3DERR_MOREDATA                                     MAKE_WINED3DHRESULT(2151)
-#define WINED3DERR_DEVICELOST                                   MAKE_WINED3DHRESULT(2152)
 #define WINED3DERR_DEVICENOTRESET                               MAKE_WINED3DHRESULT(2153)
 #define WINED3DERR_NOTAVAILABLE                                 MAKE_WINED3DHRESULT(2154)
 #define WINED3DERR_OUTOFVIDEOMEMORY                             MAKE_WINED3DHRESULT(380)
@@ -2497,12 +2496,10 @@ DWORD __cdecl wined3d_surface_get_pitch(const struct wined3d_surface *surface);
 struct wined3d_resource * __cdecl wined3d_surface_get_resource(struct wined3d_surface *surface);
 HRESULT __cdecl wined3d_surface_getdc(struct wined3d_surface *surface, HDC *dc);
 ULONG __cdecl wined3d_surface_incref(struct wined3d_surface *surface);
-HRESULT __cdecl wined3d_surface_is_lost(const struct wined3d_surface *surface);
 HRESULT __cdecl wined3d_surface_map(struct wined3d_surface *surface,
         struct wined3d_map_desc *map_desc, const struct wined3d_box *box, DWORD flags);
 void __cdecl wined3d_surface_preload(struct wined3d_surface *surface);
 HRESULT __cdecl wined3d_surface_releasedc(struct wined3d_surface *surface, HDC dc);
-HRESULT __cdecl wined3d_surface_restore(struct wined3d_surface *surface);
 HRESULT __cdecl wined3d_surface_set_overlay_position(struct wined3d_surface *surface, LONG x, LONG y);
 HRESULT __cdecl wined3d_surface_unmap(struct wined3d_surface *surface);
 HRESULT __cdecl wined3d_surface_update_overlay(struct wined3d_surface *surface, const RECT *src_rect,
-- 
2.1.4




More information about the wine-patches mailing list