ddraw: Mark surfaces as lost when the device window is deactivated.
Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
83f10e2251
commit
1ebb42ca53
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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. */
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue