From 1ebb42ca534b58221b32cbf687de2ace00b4cbfc Mon Sep 17 00:00:00 2001 From: Henri Verbeet Date: Fri, 4 Dec 2015 11:30:14 +0100 Subject: [PATCH] ddraw: Mark surfaces as lost when the device window is deactivated. Signed-off-by: Henri Verbeet Signed-off-by: Alexandre Julliard --- 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 e5217342277..ce7bef8fe4a 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 7c50031ce49..38139f8b0ee 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 f8acb2d0cac..c303ed0f80d 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 4b99dd07699..f5122b62083 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 20a342ff547..177f3ece667 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 20cd9899739..c521e515393 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 8ab097264ca..57cec093a93 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 a8f7179cfc0..29687c3639f 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 7df80fb54f9..c09e0a623ee 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 68193302e3b..abe1262ed8d 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 8b29abacf18..e38bc7d6bb3 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.11.4.GIT